]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/math/doc/html/math_toolkit/pol_tutorial/user_def_err_pol.html
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / math / doc / html / math_toolkit / pol_tutorial / user_def_err_pol.html
1 <html>
2 <head>
3 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
4 <title>Calling User Defined Error Handlers</title>
5 <link rel="stylesheet" href="../../math.css" type="text/css">
6 <meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
7 <link rel="home" href="../../index.html" title="Math Toolkit 2.5.1">
8 <link rel="up" href="../pol_tutorial.html" title="Policy Tutorial">
9 <link rel="prev" href="namespace_policies.html" title="Setting Policies at Namespace or Translation Unit Scope">
10 <link rel="next" href="understand_dis_quant.html" title="Understanding Quantiles of Discrete Distributions">
11 </head>
12 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13 <table cellpadding="2" width="100%"><tr>
14 <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
15 <td align="center"><a href="../../../../../../index.html">Home</a></td>
16 <td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
17 <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
18 <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
19 <td align="center"><a href="../../../../../../more/index.htm">More</a></td>
20 </tr></table>
21 <hr>
22 <div class="spirit-nav">
23 <a accesskey="p" href="namespace_policies.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="understand_dis_quant.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
24 </div>
25 <div class="section">
26 <div class="titlepage"><div><div><h3 class="title">
27 <a name="math_toolkit.pol_tutorial.user_def_err_pol"></a><a class="link" href="user_def_err_pol.html" title="Calling User Defined Error Handlers">Calling User
28 Defined Error Handlers</a>
29 </h3></div></div></div>
30 <p>
31 Suppose we want our own user-defined error handlers rather than the any of
32 the default ones supplied by the library to be used. If we set the policy
33 for a specific type of error to <code class="computeroutput"><span class="identifier">user_error</span></code>
34 then the library will call a user-supplied error handler. These are forward
35 declared, but not defined in boost/math/policies/error_handling.hpp like
36 this:
37 </p>
38 <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">math</span><span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">policies</span><span class="special">{</span>
39
40 <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
41 <span class="identifier">T</span> <span class="identifier">user_domain_error</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">function</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">message</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">val</span><span class="special">);</span>
42 <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
43 <span class="identifier">T</span> <span class="identifier">user_pole_error</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">function</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">message</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">val</span><span class="special">);</span>
44 <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
45 <span class="identifier">T</span> <span class="identifier">user_overflow_error</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">function</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">message</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">val</span><span class="special">);</span>
46 <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
47 <span class="identifier">T</span> <span class="identifier">user_underflow_error</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">function</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">message</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">val</span><span class="special">);</span>
48 <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
49 <span class="identifier">T</span> <span class="identifier">user_denorm_error</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">function</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">message</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">val</span><span class="special">);</span>
50 <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
51 <span class="identifier">T</span> <span class="identifier">user_evaluation_error</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">function</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">message</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">val</span><span class="special">);</span>
52 <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TargetType</span><span class="special">&gt;</span>
53 <span class="identifier">T</span> <span class="identifier">user_rounding_error</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">function</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">message</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">val</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">TargetType</span><span class="special">&amp;</span> <span class="identifier">t</span><span class="special">);</span>
54 <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
55 <span class="identifier">T</span> <span class="identifier">user_indeterminate_result_error</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">function</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">message</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">val</span><span class="special">);</span>
56
57 <span class="special">}}}</span> <span class="comment">// namespaces</span>
58 </pre>
59 <p>
60 So out first job is to include the header we want to use, and then provide
61 definitions for our user-defined error handlers that we want to use. We only
62 provide our special domain and pole error handlers; other errors like overflow
63 and underflow use the default.
64 </p>
65 <pre class="programlisting"><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">special_functions</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
66
67 <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">math</span>
68 <span class="special">{</span>
69 <span class="keyword">namespace</span> <span class="identifier">policies</span>
70 <span class="special">{</span>
71 <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
72 <span class="identifier">T</span> <span class="identifier">user_domain_error</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">function</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">message</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">val</span><span class="special">)</span>
73 <span class="special">{</span> <span class="comment">// Ignoring function, message and val for this example, perhaps unhelpfully.</span>
74 <span class="identifier">cerr</span> <span class="special">&lt;&lt;</span> <span class="string">"Domain Error!"</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
75 <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">quiet_NaN</span><span class="special">();</span>
76 <span class="special">}</span>
77
78 <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
79 <span class="identifier">T</span> <span class="identifier">user_pole_error</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">function</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">message</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">val</span><span class="special">)</span>
80 <span class="special">{</span> <span class="comment">// Ignoring function, message and val for this example, perhaps unhelpfully.</span>
81 <span class="identifier">cerr</span> <span class="special">&lt;&lt;</span> <span class="string">"Pole Error!"</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
82 <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">quiet_NaN</span><span class="special">();</span>
83 <span class="special">}</span>
84 <span class="special">}</span> <span class="comment">// namespace policies</span>
85 <span class="special">}}</span> <span class="comment">// namespace boost{ namespace math</span>
86 </pre>
87 <p>
88 Now we'll need to define a suitable policy that will call these handlers,
89 and define some forwarding functions that make use of the policy:
90 </p>
91 <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">mymath</span><span class="special">{</span>
92
93 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">policies</span><span class="special">;</span>
94
95 <span class="keyword">typedef</span> <span class="identifier">policy</span><span class="special">&lt;</span>
96 <span class="identifier">domain_error</span><span class="special">&lt;</span><span class="identifier">user_error</span><span class="special">&gt;,</span>
97 <span class="identifier">pole_error</span><span class="special">&lt;</span><span class="identifier">user_error</span><span class="special">&gt;</span>
98 <span class="special">&gt;</span> <span class="identifier">user_error_policy</span><span class="special">;</span>
99
100 <span class="identifier">BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS</span><span class="special">(</span><span class="identifier">user_error_policy</span><span class="special">)</span>
101
102 <span class="special">}</span> <span class="comment">// close unnamed namespace</span>
103 </pre>
104 <p>
105 We now have a set of forwarding functions defined in namespace mymath that
106 all look something like this:
107 </p>
108 <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">RealType</span><span class="special">&gt;</span>
109 <span class="keyword">inline</span> <span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">tools</span><span class="special">::</span><span class="identifier">promote_args</span><span class="special">&lt;</span><span class="identifier">RT</span><span class="special">&gt;::</span><span class="identifier">type</span>
110 <span class="identifier">tgamma</span><span class="special">(</span><span class="identifier">RT</span> <span class="identifier">z</span><span class="special">)</span>
111 <span class="special">{</span>
112 <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">tgamma</span><span class="special">(</span><span class="identifier">z</span><span class="special">,</span> <span class="identifier">user_error_policy</span><span class="special">());</span>
113 <span class="special">}</span>
114 </pre>
115 <p>
116 So that when we call <code class="computeroutput"><span class="identifier">mymath</span><span class="special">::</span><span class="identifier">tgamma</span><span class="special">(</span><span class="identifier">z</span><span class="special">)</span></code>
117 we really end up calling <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">tgamma</span><span class="special">(</span><span class="identifier">z</span><span class="special">,</span>
118 <span class="identifier">user_error_policy</span><span class="special">())</span></code>,
119 and any errors will get directed to our own error handlers.
120 </p>
121 <pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
122 <span class="special">{</span>
123 <span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Result of erf_inv(-10) is: "</span>
124 <span class="special">&lt;&lt;</span> <span class="identifier">mymath</span><span class="special">::</span><span class="identifier">erf_inv</span><span class="special">(-</span><span class="number">10</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
125 <span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Result of tgamma(-10) is: "</span>
126 <span class="special">&lt;&lt;</span> <span class="identifier">mymath</span><span class="special">::</span><span class="identifier">tgamma</span><span class="special">(-</span><span class="number">10</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
127 <span class="special">}</span>
128 </pre>
129 <p>
130 Which outputs:
131 </p>
132 <pre class="programlisting"> Domain Error!
133 Pole Error!
134 Result of erf_inv(-10) is: 1.#QNAN
135 Result of tgamma(-10) is: 1.#QNAN
136 </pre>
137 <p>
138 The previous example was all well and good, but the custom error handlers
139 didn't really do much of any use. In this example we'll implement all the
140 custom handlers and show how the information provided to them can be used
141 to generate nice formatted error messages.
142 </p>
143 <p>
144 Each error handler has the general form:
145 </p>
146 <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
147 <span class="identifier">T</span> <span class="identifier">user_</span><span class="emphasis"><em>error_type</em></span><span class="special">(</span>
148 <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">function</span><span class="special">,</span>
149 <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">message</span><span class="special">,</span>
150 <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">val</span><span class="special">);</span>
151 </pre>
152 <p>
153 and accepts three arguments:
154 </p>
155 <div class="variablelist">
156 <p class="title"><b></b></p>
157 <dl class="variablelist">
158 <dt><span class="term">const char* function</span></dt>
159 <dd><p>
160 The name of the function that raised the error, this string contains
161 one or more %1% format specifiers that should be replaced by the name
162 of real type T, like float or double.
163 </p></dd>
164 <dt><span class="term">const char* message</span></dt>
165 <dd><p>
166 A message associated with the error, normally this contains a %1% format
167 specifier that should be replaced with the value of <span class="emphasis"><em>value</em></span>:
168 however note that overflow and underflow messages do not contain this
169 %1% specifier (since the value of <span class="emphasis"><em>value</em></span> is immaterial
170 in these cases).
171 </p></dd>
172 <dt><span class="term">const T&amp; value</span></dt>
173 <dd><p>
174 The value that caused the error: either an argument to the function
175 if this is a domain or pole error, the tentative result if this is
176 a denorm or evaluation error, or zero or infinity for underflow or
177 overflow errors.
178 </p></dd>
179 </dl>
180 </div>
181 <p>
182 As before we'll include the headers we need first:
183 </p>
184 <pre class="programlisting"><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">special_functions</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
185 </pre>
186 <p>
187 Next we'll implement our own error handlers for each type of error, starting
188 with domain errors:
189 </p>
190 <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">math</span><span class="special">{</span>
191 <span class="keyword">namespace</span> <span class="identifier">policies</span>
192 <span class="special">{</span>
193
194 <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
195 <span class="identifier">T</span> <span class="identifier">user_domain_error</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">function</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">message</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">val</span><span class="special">)</span>
196 <span class="special">{</span>
197 </pre>
198 <p>
199 We'll begin with a bit of defensive programming in case function or message
200 are empty:
201 </p>
202 <pre class="programlisting"><span class="keyword">if</span><span class="special">(</span><span class="identifier">function</span> <span class="special">==</span> <span class="number">0</span><span class="special">)</span>
203 <span class="identifier">function</span> <span class="special">=</span> <span class="string">"Unknown function with arguments of type %1%"</span><span class="special">;</span>
204 <span class="keyword">if</span><span class="special">(</span><span class="identifier">message</span> <span class="special">==</span> <span class="number">0</span><span class="special">)</span>
205 <span class="identifier">message</span> <span class="special">=</span> <span class="string">"Cause unknown with bad argument %1%"</span><span class="special">;</span>
206 </pre>
207 <p>
208 Next we'll format the name of the function with the name of type T, perhaps
209 double:
210 </p>
211 <pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">(</span><span class="string">"Error in function "</span><span class="special">);</span>
212 <span class="identifier">msg</span> <span class="special">+=</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="identifier">function</span><span class="special">)</span> <span class="special">%</span> <span class="keyword">typeid</span><span class="special">(</span><span class="identifier">T</span><span class="special">).</span><span class="identifier">name</span><span class="special">()).</span><span class="identifier">str</span><span class="special">();</span>
213 </pre>
214 <p>
215 Then likewise format the error message with the value of parameter <span class="emphasis"><em>val</em></span>,
216 making sure we output all the potentially significant digits of <span class="emphasis"><em>val</em></span>:
217 </p>
218 <pre class="programlisting"><span class="identifier">msg</span> <span class="special">+=</span> <span class="string">": \n"</span><span class="special">;</span>
219 <span class="keyword">int</span> <span class="identifier">prec</span> <span class="special">=</span> <span class="number">2</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">digits</span> <span class="special">*</span> <span class="number">30103UL</span><span class="special">)</span> <span class="special">/</span> <span class="number">100000UL</span><span class="special">;</span>
220 <span class="comment">// int prec = std::numeric_limits&lt;T&gt;::max_digits10; // For C++0X Standard Library</span>
221 <span class="identifier">msg</span> <span class="special">+=</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="identifier">message</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">io</span><span class="special">::</span><span class="identifier">group</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">setprecision</span><span class="special">(</span><span class="identifier">prec</span><span class="special">),</span> <span class="identifier">val</span><span class="special">)).</span><span class="identifier">str</span><span class="special">();</span>
222 </pre>
223 <p>
224 Now we just have to do something with the message, we could throw an exception,
225 but for the purposes of this example we'll just dump the message to std::cerr:
226 </p>
227 <pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span> <span class="special">&lt;&lt;</span> <span class="identifier">msg</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>
228 </pre>
229 <p>
230 Finally the only sensible value we can return from a domain error is a NaN:
231 </p>
232 <pre class="programlisting"> <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">quiet_NaN</span><span class="special">();</span>
233 <span class="special">}</span>
234 </pre>
235 <p>
236 Pole errors are essentially a special case of domain errors, so in this example
237 we'll just return the result of a domain error:
238 </p>
239 <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
240 <span class="identifier">T</span> <span class="identifier">user_pole_error</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">function</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">message</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">val</span><span class="special">)</span>
241 <span class="special">{</span>
242 <span class="keyword">return</span> <span class="identifier">user_domain_error</span><span class="special">(</span><span class="identifier">function</span><span class="special">,</span> <span class="identifier">message</span><span class="special">,</span> <span class="identifier">val</span><span class="special">);</span>
243 <span class="special">}</span>
244 </pre>
245 <p>
246 Overflow errors are very similar to domain errors, except that there's no
247 %1% format specifier in the <span class="emphasis"><em>message</em></span> parameter:
248 </p>
249 <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
250 <span class="identifier">T</span> <span class="identifier">user_overflow_error</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">function</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">message</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">val</span><span class="special">)</span>
251 <span class="special">{</span>
252 <span class="keyword">if</span><span class="special">(</span><span class="identifier">function</span> <span class="special">==</span> <span class="number">0</span><span class="special">)</span>
253 <span class="identifier">function</span> <span class="special">=</span> <span class="string">"Unknown function with arguments of type %1%"</span><span class="special">;</span>
254 <span class="keyword">if</span><span class="special">(</span><span class="identifier">message</span> <span class="special">==</span> <span class="number">0</span><span class="special">)</span>
255 <span class="identifier">message</span> <span class="special">=</span> <span class="string">"Result of function is too large to represent"</span><span class="special">;</span>
256
257 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">(</span><span class="string">"Error in function "</span><span class="special">);</span>
258 <span class="identifier">msg</span> <span class="special">+=</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="identifier">function</span><span class="special">)</span> <span class="special">%</span> <span class="keyword">typeid</span><span class="special">(</span><span class="identifier">T</span><span class="special">).</span><span class="identifier">name</span><span class="special">()).</span><span class="identifier">str</span><span class="special">();</span>
259
260 <span class="identifier">msg</span> <span class="special">+=</span> <span class="string">": \n"</span><span class="special">;</span>
261 <span class="identifier">msg</span> <span class="special">+=</span> <span class="identifier">message</span><span class="special">;</span>
262
263 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span> <span class="special">&lt;&lt;</span> <span class="identifier">msg</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>
264
265 <span class="comment">// Value passed to the function is an infinity, just return it:</span>
266 <span class="keyword">return</span> <span class="identifier">val</span><span class="special">;</span>
267 <span class="special">}</span>
268 </pre>
269 <p>
270 Underflow errors are much the same as overflow:
271 </p>
272 <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
273 <span class="identifier">T</span> <span class="identifier">user_underflow_error</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">function</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">message</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">val</span><span class="special">)</span>
274 <span class="special">{</span>
275 <span class="keyword">if</span><span class="special">(</span><span class="identifier">function</span> <span class="special">==</span> <span class="number">0</span><span class="special">)</span>
276 <span class="identifier">function</span> <span class="special">=</span> <span class="string">"Unknown function with arguments of type %1%"</span><span class="special">;</span>
277 <span class="keyword">if</span><span class="special">(</span><span class="identifier">message</span> <span class="special">==</span> <span class="number">0</span><span class="special">)</span>
278 <span class="identifier">message</span> <span class="special">=</span> <span class="string">"Result of function is too small to represent"</span><span class="special">;</span>
279
280 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">(</span><span class="string">"Error in function "</span><span class="special">);</span>
281 <span class="identifier">msg</span> <span class="special">+=</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="identifier">function</span><span class="special">)</span> <span class="special">%</span> <span class="keyword">typeid</span><span class="special">(</span><span class="identifier">T</span><span class="special">).</span><span class="identifier">name</span><span class="special">()).</span><span class="identifier">str</span><span class="special">();</span>
282
283 <span class="identifier">msg</span> <span class="special">+=</span> <span class="string">": \n"</span><span class="special">;</span>
284 <span class="identifier">msg</span> <span class="special">+=</span> <span class="identifier">message</span><span class="special">;</span>
285
286 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span> <span class="special">&lt;&lt;</span> <span class="identifier">msg</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>
287
288 <span class="comment">// Value passed to the function is zero, just return it:</span>
289 <span class="keyword">return</span> <span class="identifier">val</span><span class="special">;</span>
290 <span class="special">}</span>
291 </pre>
292 <p>
293 Denormalised results are much the same as underflow:
294 </p>
295 <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
296 <span class="identifier">T</span> <span class="identifier">user_denorm_error</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">function</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">message</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">val</span><span class="special">)</span>
297 <span class="special">{</span>
298 <span class="keyword">if</span><span class="special">(</span><span class="identifier">function</span> <span class="special">==</span> <span class="number">0</span><span class="special">)</span>
299 <span class="identifier">function</span> <span class="special">=</span> <span class="string">"Unknown function with arguments of type %1%"</span><span class="special">;</span>
300 <span class="keyword">if</span><span class="special">(</span><span class="identifier">message</span> <span class="special">==</span> <span class="number">0</span><span class="special">)</span>
301 <span class="identifier">message</span> <span class="special">=</span> <span class="string">"Result of function is denormalised"</span><span class="special">;</span>
302
303 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">(</span><span class="string">"Error in function "</span><span class="special">);</span>
304 <span class="identifier">msg</span> <span class="special">+=</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="identifier">function</span><span class="special">)</span> <span class="special">%</span> <span class="keyword">typeid</span><span class="special">(</span><span class="identifier">T</span><span class="special">).</span><span class="identifier">name</span><span class="special">()).</span><span class="identifier">str</span><span class="special">();</span>
305
306 <span class="identifier">msg</span> <span class="special">+=</span> <span class="string">": \n"</span><span class="special">;</span>
307 <span class="identifier">msg</span> <span class="special">+=</span> <span class="identifier">message</span><span class="special">;</span>
308
309 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span> <span class="special">&lt;&lt;</span> <span class="identifier">msg</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>
310
311 <span class="comment">// Value passed to the function is denormalised, just return it:</span>
312 <span class="keyword">return</span> <span class="identifier">val</span><span class="special">;</span>
313 <span class="special">}</span>
314 </pre>
315 <p>
316 Which leaves us with evaluation errors: these occur when an internal error
317 occurs that prevents the function being fully evaluated. The parameter <span class="emphasis"><em>val</em></span>
318 contains the closest approximation to the result found so far:
319 </p>
320 <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
321 <span class="identifier">T</span> <span class="identifier">user_evaluation_error</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">function</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">message</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">val</span><span class="special">)</span>
322 <span class="special">{</span>
323 <span class="keyword">if</span><span class="special">(</span><span class="identifier">function</span> <span class="special">==</span> <span class="number">0</span><span class="special">)</span>
324 <span class="identifier">function</span> <span class="special">=</span> <span class="string">"Unknown function with arguments of type %1%"</span><span class="special">;</span>
325 <span class="keyword">if</span><span class="special">(</span><span class="identifier">message</span> <span class="special">==</span> <span class="number">0</span><span class="special">)</span>
326 <span class="identifier">message</span> <span class="special">=</span> <span class="string">"An internal evaluation error occurred with "</span>
327 <span class="string">"the best value calculated so far of %1%"</span><span class="special">;</span>
328
329 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">(</span><span class="string">"Error in function "</span><span class="special">);</span>
330 <span class="identifier">msg</span> <span class="special">+=</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="identifier">function</span><span class="special">)</span> <span class="special">%</span> <span class="keyword">typeid</span><span class="special">(</span><span class="identifier">T</span><span class="special">).</span><span class="identifier">name</span><span class="special">()).</span><span class="identifier">str</span><span class="special">();</span>
331
332 <span class="identifier">msg</span> <span class="special">+=</span> <span class="string">": \n"</span><span class="special">;</span>
333 <span class="keyword">int</span> <span class="identifier">prec</span> <span class="special">=</span> <span class="number">2</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">digits</span> <span class="special">*</span> <span class="number">30103UL</span><span class="special">)</span> <span class="special">/</span> <span class="number">100000UL</span><span class="special">;</span>
334 <span class="comment">// int prec = std::numeric_limits&lt;T&gt;::max_digits10; // For C++0X Standard Library</span>
335 <span class="identifier">msg</span> <span class="special">+=</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="identifier">message</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">io</span><span class="special">::</span><span class="identifier">group</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">setprecision</span><span class="special">(</span><span class="identifier">prec</span><span class="special">),</span> <span class="identifier">val</span><span class="special">)).</span><span class="identifier">str</span><span class="special">();</span>
336
337 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span> <span class="special">&lt;&lt;</span> <span class="identifier">msg</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>
338
339 <span class="comment">// What do we return here? This is generally a fatal error, that should never occur,</span>
340 <span class="comment">// so we just return a NaN for the purposes of the example:</span>
341 <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">quiet_NaN</span><span class="special">();</span>
342 <span class="special">}</span>
343
344 <span class="special">}</span> <span class="comment">// policies</span>
345 <span class="special">}}</span> <span class="comment">// boost::math</span>
346 </pre>
347 <p>
348 Now we'll need to define a suitable policy that will call these handlers,
349 and define some forwarding functions that make use of the policy:
350 </p>
351 <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">mymath</span>
352 <span class="special">{</span> <span class="comment">// unnamed.</span>
353
354 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">policies</span><span class="special">;</span>
355
356 <span class="keyword">typedef</span> <span class="identifier">policy</span><span class="special">&lt;</span>
357 <span class="identifier">domain_error</span><span class="special">&lt;</span><span class="identifier">user_error</span><span class="special">&gt;,</span>
358 <span class="identifier">pole_error</span><span class="special">&lt;</span><span class="identifier">user_error</span><span class="special">&gt;,</span>
359 <span class="identifier">overflow_error</span><span class="special">&lt;</span><span class="identifier">user_error</span><span class="special">&gt;,</span>
360 <span class="identifier">underflow_error</span><span class="special">&lt;</span><span class="identifier">user_error</span><span class="special">&gt;,</span>
361 <span class="identifier">denorm_error</span><span class="special">&lt;</span><span class="identifier">user_error</span><span class="special">&gt;,</span>
362 <span class="identifier">evaluation_error</span><span class="special">&lt;</span><span class="identifier">user_error</span><span class="special">&gt;</span>
363 <span class="special">&gt;</span> <span class="identifier">user_error_policy</span><span class="special">;</span>
364
365 <span class="identifier">BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS</span><span class="special">(</span><span class="identifier">user_error_policy</span><span class="special">)</span>
366
367 <span class="special">}</span> <span class="comment">// unnamed namespace</span>
368 </pre>
369 <p>
370 We now have a set of forwarding functions, defined in namespace mymath, that
371 all look something like this:
372 </p>
373 <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">RealType</span><span class="special">&gt;</span>
374 <span class="keyword">inline</span> <span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">tools</span><span class="special">::</span><span class="identifier">promote_args</span><span class="special">&lt;</span><span class="identifier">RT</span><span class="special">&gt;::</span><span class="identifier">type</span>
375 <span class="identifier">tgamma</span><span class="special">(</span><span class="identifier">RT</span> <span class="identifier">z</span><span class="special">)</span>
376 <span class="special">{</span>
377 <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">tgamma</span><span class="special">(</span><span class="identifier">z</span><span class="special">,</span> <span class="identifier">user_error_policy</span><span class="special">());</span>
378 <span class="special">}</span>
379 </pre>
380 <p>
381 So that when we call <code class="computeroutput"><span class="identifier">mymath</span><span class="special">::</span><span class="identifier">tgamma</span><span class="special">(</span><span class="identifier">z</span><span class="special">)</span></code>
382 we really end up calling <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">tgamma</span><span class="special">(</span><span class="identifier">z</span><span class="special">,</span>
383 <span class="identifier">user_error_policy</span><span class="special">())</span></code>,
384 and any errors will get directed to our own error handlers:
385 </p>
386 <pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
387 <span class="special">{</span>
388 <span class="comment">// Raise a domain error:</span>
389 <span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Result of erf_inv(-10) is: "</span>
390 <span class="special">&lt;&lt;</span> <span class="identifier">mymath</span><span class="special">::</span><span class="identifier">erf_inv</span><span class="special">(-</span><span class="number">10</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">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
391 <span class="comment">// Raise a pole error:</span>
392 <span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Result of tgamma(-10) is: "</span>
393 <span class="special">&lt;&lt;</span> <span class="identifier">mymath</span><span class="special">::</span><span class="identifier">tgamma</span><span class="special">(-</span><span class="number">10</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">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
394 <span class="comment">// Raise an overflow error:</span>
395 <span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Result of tgamma(3000) is: "</span>
396 <span class="special">&lt;&lt;</span> <span class="identifier">mymath</span><span class="special">::</span><span class="identifier">tgamma</span><span class="special">(</span><span class="number">3000</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">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
397 <span class="comment">// Raise an underflow error:</span>
398 <span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Result of tgamma(-190.5) is: "</span>
399 <span class="special">&lt;&lt;</span> <span class="identifier">mymath</span><span class="special">::</span><span class="identifier">tgamma</span><span class="special">(-</span><span class="number">190.5</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">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
400 <span class="comment">// Unfortunately we can't predicably raise a denormalised</span>
401 <span class="comment">// result, nor can we raise an evaluation error in this example</span>
402 <span class="comment">// since these should never really occur!</span>
403 <span class="special">}</span> <span class="comment">// int main()</span>
404 </pre>
405 <p>
406 Which outputs:
407 </p>
408 <pre class="programlisting">Error in function boost::math::erf_inv&lt;double&gt;(double, double):
409 Argument outside range [-1, 1] in inverse erf function (got p=-10).
410 Result of erf_inv(-10) is: 1.#QNAN
411
412 Error in function boost::math::tgamma&lt;long double&gt;(long double):
413 Evaluation of tgamma at a negative integer -10.
414 Result of tgamma(-10) is: 1.#QNAN
415
416 Error in function boost::math::tgamma&lt;long double&gt;(long double):
417 Result of tgamma is too large to represent.
418 Error in function boost::math::tgamma&lt;double&gt;(double):
419 Result of function is too large to represent
420 Result of tgamma(3000) is: 1.#INF
421
422 Error in function boost::math::tgamma&lt;long double&gt;(long double):
423 Result of tgamma is too large to represent.
424 Error in function boost::math::tgamma&lt;long double&gt;(long double):
425 Result of tgamma is too small to represent.
426 Result of tgamma(-190.5) is: 0
427 </pre>
428 <p>
429 Notice how some of the calls result in an error handler being called more
430 than once, or for more than one handler to be called: this is an artefact
431 of the fact that many functions are implemented in terms of one or more sub-routines
432 each of which may have it's own error handling. For example <code class="computeroutput"><span class="identifier">tgamma</span><span class="special">(-</span><span class="number">190.5</span><span class="special">)</span></code> is implemented
433 in terms of <code class="computeroutput"><span class="identifier">tgamma</span><span class="special">(</span><span class="number">190.5</span><span class="special">)</span></code> - which
434 overflows - the reflection formula for <code class="computeroutput"><span class="identifier">tgamma</span></code>
435 then notices that it is dividing by infinity and so underflows.
436 </p>
437 </div>
438 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
439 <td align="left"></td>
440 <td align="right"><div class="copyright-footer">Copyright &#169; 2006-2010, 2012-2014 Nikhar Agrawal,
441 Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
442 Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan R&#229;de, Gautam Sewani,
443 Benjamin Sobotta, Thijs van den Berg, Daryle Walker and Xiaogang Zhang<p>
444 Distributed under the Boost Software License, Version 1.0. (See accompanying
445 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>)
446 </p>
447 </div></td>
448 </tr></table>
449 <hr>
450 <div class="spirit-nav">
451 <a accesskey="p" href="namespace_policies.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="understand_dis_quant.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
452 </div>
453 </body>
454 </html>