summaryrefslogtreecommitdiff
path: root/libs/math/doc/html/math_toolkit/pol_tutorial/changing_policy_defaults.html
blob: bf905d7d394b7a0759fdca250dd966f571953770 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Changing the Policy Defaults</title>
<link rel="stylesheet" href="../../math.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
<link rel="home" href="../../index.html" title="Math Toolkit 2.2.0">
<link rel="up" href="../pol_tutorial.html" title="Policy Tutorial">
<link rel="prev" href="policy_usage.html" title="So How are Policies Used Anyway?">
<link rel="next" href="ad_hoc_dist_policies.html" title="Setting Policies for Distributions on an Ad Hoc Basis">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="policy_usage.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../pol_tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="ad_hoc_dist_policies.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="math_toolkit.pol_tutorial.changing_policy_defaults"></a><a class="link" href="changing_policy_defaults.html" title="Changing the Policy Defaults">Changing
      the Policy Defaults</a>
</h3></div></div></div>
<p>
        The default policies used by the library are changed by the usual configuration
        macro method.
      </p>
<p>
        For example, passing <code class="computeroutput"><span class="special">-</span><span class="identifier">DBOOST_MATH_DOMAIN_ERROR_POLICY</span><span class="special">=</span><span class="identifier">errno_on_error</span></code>
        to your compiler will cause domain errors to set <code class="computeroutput"><span class="special">::</span><span class="identifier">errno</span></code> and return a <a href="http://en.wikipedia.org/wiki/NaN" target="_top">NaN</a>
        rather than the usual default behaviour of throwing a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">domain_error</span></code>
        exception.
      </p>
<div class="tip"><table border="0" summary="Tip">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td>
<th align="left">Tip</th>
</tr>
<tr><td align="left" valign="top">
<p>
          For Microsoft Visual Studio,you can add to the Project Property Page, C/C++,
          Preprocessor, Preprocessor definitions like:
        </p>
<pre class="programlisting"><span class="identifier">BOOST_MATH_ASSERT_UNDEFINED_POLICY</span><span class="special">=</span><span class="number">0</span>
<span class="identifier">BOOST_MATH_OVERFLOW_ERROR_POLICY</span><span class="special">=</span><span class="identifier">errno_on_error</span></pre>
<p>
          This may be helpful to avoid complications with pre-compiled headers that
          may mean that the equivalent definitions in source code:
        </p>
<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">BOOST_MATH_ASSERT_UNDEFINED_POLICY</span> <span class="keyword">false</span>
<span class="preprocessor">#define</span> <span class="identifier">BOOST_MATH_OVERFLOW_ERROR_POLICY</span> <span class="identifier">errno_on_error</span></pre>
<p>
          <span class="bold"><strong>may be ignored</strong></span>.
        </p>
<p>
          The compiler command line shows:
        </p>
<pre class="programlisting"><span class="special">/</span><span class="identifier">D</span> <span class="string">"BOOST_MATH_ASSERT_UNDEFINED_POLICY=0"</span>
<span class="special">/</span><span class="identifier">D</span> <span class="string">"BOOST_MATH_OVERFLOW_ERROR_POLICY=errno_on_error"</span></pre>
</td></tr>
</table></div>
<p>
        There is however a very important caveat to this:
      </p>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top">
<p>
          <span class="bold"><strong><span class="emphasis"><em>Default policies changed by setting configuration
          macros must be changed uniformly in every translation unit in the program.</em></span></strong></span>
        </p>
<p>
          Failure to follow this rule may result in violations of the "One Definition
          Rule (ODR)" and result in unpredictable program behaviour.
        </p>
</td></tr>
</table></div>
<p>
        That means there are only two safe ways to use these macros:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            Edit them in <a href="../../../../../../boost/math/tools/user.hpp" target="_top">boost/math/tools/user.hpp</a>,
            so that the defaults are set on an installation-wide basis. Unfortunately
            this may not be convenient if you are using a pre-installed Boost distribution
            (on Linux for example).
          </li>
<li class="listitem">
            Set the defines in your project's Makefile or build environment, so that
            they are set uniformly across all translation units.
          </li>
</ul></div>
<p>
        What you should <span class="bold"><strong>not</strong></span> do is:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
            Set the defines in the source file using <code class="computeroutput"><span class="preprocessor">#define</span></code>
            as doing so almost certainly will break your program, unless you're absolutely
            certain that the program is restricted to a single translation unit.
          </li></ul></div>
<p>
        And, yes, you will find examples in our test programs where we break this
        rule: but only because we know there will always be a single translation
        unit only: <span class="emphasis"><em>don't say that you weren't warned!</em></span>
      </p>
<p>
        The following example demonstrates the effect of setting the macro BOOST_MATH_DOMAIN_ERROR_POLICY
        when an invalid argument is encountered. For the purposes of this example,
        we'll pass a negative degrees of freedom parameter to the student's t distribution.
      </p>
<p>
        Since we know that this is a single file program we could just add:
      </p>
<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">BOOST_MATH_DOMAIN_ERROR_POLICY</span> <span class="identifier">ignore_error</span>
</pre>
<p>
        to the top of the source file to change the default policy to one that simply
        returns a NaN when a domain error occurs. Alternatively we could use:
      </p>
<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">BOOST_MATH_DOMAIN_ERROR_POLICY</span> <span class="identifier">errno_on_error</span>
</pre>
<p>
        To ensure the <code class="computeroutput"><span class="special">::</span><span class="identifier">errno</span></code>
        is set when a domain error occurs as well as returning a NaN.
      </p>
<p>
        This is safe provided the program consists of a single translation unit
        <span class="emphasis"><em>and</em></span> we place the define <span class="emphasis"><em>before</em></span>
        any #includes. Note that should we add the define after the includes then
        it will have no effect! A warning such as:
      </p>
<pre class="programlisting">warning C4005: 'BOOST_MATH_OVERFLOW_ERROR_POLICY' : macro redefinition</pre>
<p>
        is a certain sign that it will <span class="emphasis"><em>not</em></span> have the desired
        effect.
      </p>
<p>
        We'll begin our sample program with the needed includes:
      </p>
<pre class="programlisting">   <span class="preprocessor">#define</span> <span class="identifier">BOOST_MATH_DOMAIN_ERROR_POLICY</span> <span class="identifier">ignore_error</span>

<span class="comment">// Boost</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">distributions</span><span class="special">/</span><span class="identifier">students_t</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
   <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">students_t</span><span class="special">;</span>  <span class="comment">// Probability of students_t(df, t).</span>

<span class="comment">// std</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
   <span class="keyword">using</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">;</span>
   <span class="keyword">using</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>

<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">stdexcept</span><span class="special">&gt;</span>
   <span class="keyword">using</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">exception</span><span class="special">;</span>

<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cstddef</span><span class="special">&gt;</span>
   <span class="comment">// using ::errno</span>
</pre>
<p>
        Next we'll define the program's main() to call the student's t distribution
        with an invalid degrees of freedom parameter, the program is set up to handle
        either an exception or a NaN:
      </p>
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
   <span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Example error handling using Student's t function. "</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
   <span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"BOOST_MATH_DOMAIN_ERROR_POLICY is set to: "</span>
      <span class="special">&lt;&lt;</span> <span class="identifier">BOOST_STRINGIZE</span><span class="special">(</span><span class="identifier">BOOST_MATH_DOMAIN_ERROR_POLICY</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>

   <span class="keyword">double</span> <span class="identifier">degrees_of_freedom</span> <span class="special">=</span> <span class="special">-</span><span class="number">1</span><span class="special">;</span> <span class="comment">// A bad argument!</span>
   <span class="keyword">double</span> <span class="identifier">t</span> <span class="special">=</span> <span class="number">10</span><span class="special">;</span>

   <span class="keyword">try</span>
   <span class="special">{</span>
      <span class="identifier">errno</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="comment">// Clear/reset.</span>
      <span class="identifier">students_t</span> <span class="identifier">dist</span><span class="special">(</span><span class="identifier">degrees_of_freedom</span><span class="special">);</span> <span class="comment">// exception is thrown here if enabled.</span>
      <span class="keyword">double</span> <span class="identifier">p</span> <span class="special">=</span> <span class="identifier">cdf</span><span class="special">(</span><span class="identifier">dist</span><span class="special">,</span> <span class="identifier">t</span><span class="special">);</span>
      <span class="comment">// Test for error reported by other means:</span>
      <span class="keyword">if</span><span class="special">((</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">isnan</span><span class="special">)(</span><span class="identifier">p</span><span class="special">))</span>
      <span class="special">{</span>
         <span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"cdf returned a NaN!"</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
         <span class="keyword">if</span> <span class="special">(</span><span class="identifier">errno</span> <span class="special">!=</span> <span class="number">0</span><span class="special">)</span>
         <span class="special">{</span> <span class="comment">// So errno has been set.</span>
           <span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"errno is set to: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">errno</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
         <span class="special">}</span>
      <span class="special">}</span>
      <span class="keyword">else</span>
         <span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Probability of Student's t is "</span> <span class="special">&lt;&lt;</span> <span class="identifier">p</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
   <span class="special">}</span>
   <span class="keyword">catch</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">exception</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span>
   <span class="special">{</span>
      <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span>
         <span class="string">"\n"</span><span class="string">"Message from thrown exception was:\n   "</span> <span class="special">&lt;&lt;</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
   <span class="special">}</span>
   <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span> <span class="comment">// int main()</span>
</pre>
<p>
        Here's what the program output looks like with a default build (one that
        <span class="bold"><strong>does throw exceptions</strong></span>):
      </p>
<pre class="programlisting">Example error handling using Student's t function.
BOOST_MATH_DOMAIN_ERROR_POLICY is set to: throw_on_error

Message from thrown exception was:
   Error in function boost::math::students_t_distribution&lt;double&gt;::students_t_distribution:
   Degrees of freedom argument is -1, but must be &gt; 0 !
</pre>
<p>
        Alternatively let's build with:
      </p>
<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">BOOST_MATH_DOMAIN_ERROR_POLICY</span> <span class="identifier">ignore_error</span>
</pre>
<p>
        Now the program output is:
      </p>
<pre class="programlisting">Example error handling using Student's t function.
BOOST_MATH_DOMAIN_ERROR_POLICY is set to: ignore_error
cdf returned a NaN!
</pre>
<p>
        And finally let's build with:
      </p>
<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">BOOST_MATH_DOMAIN_ERROR_POLICY</span> <span class="identifier">errno_on_error</span>
</pre>
<p>
        Which gives the output show errno:
      </p>
<pre class="programlisting">Example error handling using Student's t function.
BOOST_MATH_DOMAIN_ERROR_POLICY is set to: errno_on_error
cdf returned a NaN!
errno is set to: 33
</pre>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2006-2010, 2012-2014 Nikhar Agrawal,
      Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
      Holin, Bruno Lalande, John Maddock, Johan R&#229;de, Gautam Sewani, Benjamin Sobotta,
      Thijs van den Berg, Daryle Walker and Xiaogang Zhang<p>
        Distributed under the Boost Software License, Version 1.0. (See accompanying
        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
      </p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="policy_usage.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../pol_tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="ad_hoc_dist_policies.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>