summaryrefslogtreecommitdiff
path: root/libs/math/doc/sf_and_dist/html/math_toolkit/special/powers/ct_pow.html
blob: 3e1f64d13b4d6b4c04873f90812e4a226efef5fa (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
259
260
261
262
263
264
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Compile Time Power of a Runtime Base</title>
<link rel="stylesheet" href="../../../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
<link rel="home" href="../../../index.html" title="Math Toolkit">
<link rel="up" href="../powers.html" title="Logs, Powers, Roots and Exponentials">
<link rel="prev" href="hypot.html" title="hypot">
<link rel="next" href="../sinc.html" title="Sinus Cardinal and Hyperbolic Sinus Cardinal Functions">
</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="hypot.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../powers.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="../sinc.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section math_toolkit_special_powers_ct_pow">
<div class="titlepage"><div><div><h4 class="title">
<a name="math_toolkit.special.powers.ct_pow"></a><a class="link" href="ct_pow.html" title="Compile Time Power of a Runtime Base">Compile Time Power
        of a Runtime Base</a>
</h4></div></div></div>
<p>
          The <code class="computeroutput"><span class="identifier">pow</span></code> function effectively
          computes the compile-time integral power of a run-time base.
        </p>
<h5>
<a name="math_toolkit.special.powers.ct_pow.h0"></a>
          <span><a name="math_toolkit.special.powers.ct_pow.synopsis"></a></span><a class="link" href="ct_pow.html#math_toolkit.special.powers.ct_pow.synopsis">Synopsis</a>
        </h5>
<p>
          <a href="../../../../../../../../boost/math/special_functions/pow.hpp" target="_top"><code class="computeroutput"><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">pow</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code></a>
        </p>
<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">template</span> <span class="special">&lt;</span><span class="keyword">int</span> <span class="identifier">N</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
<a class="link" href="../../main_overview/result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">pow</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">base</span><span class="special">);</span>

<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">int</span> <span class="identifier">N</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Policy</span><span class="special">&gt;</span>
<a class="link" href="../../main_overview/result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">pow</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">base</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Policy</span><span class="special">&amp;</span> <span class="identifier">policy</span><span class="special">);</span>

<span class="special">}}</span>
</pre>
<h5>
<a name="math_toolkit.special.powers.ct_pow.h1"></a>
          <span><a name="math_toolkit.special.powers.ct_pow.rationale_and_usage"></a></span><a class="link" href="ct_pow.html#math_toolkit.special.powers.ct_pow.rationale_and_usage">Rationale
          and Usage</a>
        </h5>
<p>
          Computing the power of a number with an exponent that is known at compile
          time is a common need for programmers. In such cases, the usual method
          is to avoid the overhead implied by the <code class="computeroutput"><span class="identifier">pow</span></code>,
          <code class="computeroutput"><span class="identifier">powf</span></code> and <code class="computeroutput"><span class="identifier">powl</span></code> C functions by hardcoding an expression
          such as:
        </p>
<pre class="programlisting"><span class="comment">// Hand-written 8th power of a 'base' variable</span>
<span class="keyword">double</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">;</span>
</pre>
<p>
          However, this kind of expression is not really readable (knowing the value
          of the exponent involves counting the number of occurrences of <span class="emphasis"><em>base</em></span>),
          error-prone (it's easy to forget an occurrence), syntactically bulky, and
          non-optimal in terms of performance.
        </p>
<p>
          The pow function of Boost.Math helps writing this kind expression along
          with solving all the problems listed above:
        </p>
<pre class="programlisting"><span class="comment">// 8th power of a 'base' variable using math::pow</span>
<span class="keyword">double</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">pow</span><span class="special">&lt;</span><span class="number">8</span><span class="special">&gt;(</span><span class="identifier">base</span><span class="special">);</span>
</pre>
<p>
          The expression is now shorter, easier to read, safer, and even faster.
          Indeed, <code class="computeroutput"><span class="identifier">pow</span></code> will compute
          the expression such that only log2(N) products are made for a power of
          N. For instance in the example above, the resulting expression will be
          the same as if we had written this, with only one computation of each identical
          subexpression:
        </p>
<pre class="programlisting"><span class="comment">// Internal effect of pow&lt;8&gt;(base)</span>
<span class="keyword">double</span> <span class="identifier">result</span> <span class="special">=</span> <span class="special">((</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">)*(</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">))*((</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">)*(</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">));</span>
</pre>
<p>
          Only 3 different products were actually computed.
        </p>
<h5>
<a name="math_toolkit.special.powers.ct_pow.h2"></a>
          <span><a name="math_toolkit.special.powers.ct_pow.return_type"></a></span><a class="link" href="ct_pow.html#math_toolkit.special.powers.ct_pow.return_type">Return
          Type</a>
        </h5>
<p>
          The return type of these functions is computed using the <a class="link" href="../../main_overview/result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>result
          type calculation rules</em></span></a>. For example:
        </p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
              If T is a <code class="computeroutput"><span class="keyword">float</span></code>, the return
              type is a <code class="computeroutput"><span class="keyword">float</span></code>.
            </li>
<li class="listitem">
              If T is a <code class="computeroutput"><span class="keyword">long</span> <span class="keyword">double</span></code>,
              the return type is a <code class="computeroutput"><span class="keyword">long</span> <span class="keyword">double</span></code>.
            </li>
<li class="listitem">
              Otherwise, the return type is a <code class="computeroutput"><span class="keyword">double</span></code>.
            </li>
</ul></div>
<h5>
<a name="math_toolkit.special.powers.ct_pow.h3"></a>
          <span><a name="math_toolkit.special.powers.ct_pow.policies"></a></span><a class="link" href="ct_pow.html#math_toolkit.special.powers.ct_pow.policies">Policies</a>
        </h5>
<p>
          The final <a class="link" href="../../policy.html" title="Policies">Policy</a> argument is
          optional and can be used to control the behaviour of the function: how
          it handles errors, what level of precision to use etc. Refer to the <a class="link" href="../../policy.html" title="Policies">policy documentation for more details</a>.
        </p>
<h5>
<a name="math_toolkit.special.powers.ct_pow.h4"></a>
          <span><a name="math_toolkit.special.powers.ct_pow.error_handling"></a></span><a class="link" href="ct_pow.html#math_toolkit.special.powers.ct_pow.error_handling">Error
          Handling</a>
        </h5>
<p>
          Two cases of errors can occur when using <code class="computeroutput"><span class="identifier">pow</span></code>:
        </p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
              In case of null base and negative exponent, an <a class="link" href="../../main_overview/error_handling.html#overflow_error">overflow_error</a>
              occurs since this operation is a division by 0 (it equals to 1/0).
            </li>
<li class="listitem">
              In case of null base and null exponent, an <a class="link" href="../../main_overview/error_handling.html#indeterminate_result_error">indeterminate_result_error</a>
              occurs since the result of this operation is indeterminate. Those errors
              follow the <a class="link" href="../../main_overview/error_handling.html" title="Error Handling">general
              policies of error handling in Boost.Math</a>.
            </li>
</ul></div>
<p>
          The default overflow error policy is <code class="computeroutput"><span class="identifier">throw_on_error</span></code>.
          A call like <code class="computeroutput"><span class="identifier">pow</span><span class="special">&lt;-</span><span class="number">2</span><span class="special">&gt;(</span><span class="number">0</span><span class="special">)</span></code> will thus throw a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">overflow_error</span></code>
          exception. As shown in the link given above, other error handling policies
          can be used:
        </p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
              <code class="computeroutput"><span class="identifier">errno_on_error</span></code>: Sets
              <code class="computeroutput"><span class="special">::</span><span class="identifier">errno</span></code>
              to <code class="computeroutput"><span class="identifier">ERANGE</span></code> and returns
              <code class="computeroutput"><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">infinity</span><span class="special">()</span></code>.
            </li>
<li class="listitem">
              <code class="computeroutput"><span class="identifier">ignore_error</span></code>: Returns
              <code class="computeroutput"><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">infinity</span><span class="special">()</span></code>.
            </li>
<li class="listitem">
              <code class="computeroutput"><span class="identifier">user_error</span></code>: Returns
              the result of <code class="computeroutput"><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><span class="identifier">user_overflow_error</span></code>:
              this function must be defined by the user.
            </li>
</ul></div>
<p>
          The default indeterminate result error policy is <code class="computeroutput"><span class="identifier">ignore_error</span></code>,
          which for this function returns 1 since it's the most commonly chosen result
          for a power of 0. Here again, other error handling policies can be used:
        </p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
              <code class="computeroutput"><span class="identifier">throw_on_error</span></code>: Throws
              <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">domain_error</span></code>
            </li>
<li class="listitem">
              <code class="computeroutput"><span class="identifier">errno_on_error</span></code>: Sets
              <code class="computeroutput"><span class="special">::</span><span class="identifier">errno</span></code>
              to <code class="computeroutput"><span class="identifier">EDOM</span></code> and returns
              1.
            </li>
<li class="listitem">
              <code class="computeroutput"><span class="identifier">user_error</span></code>: Returns
              the result of <code class="computeroutput"><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><span class="identifier">user_indeterminate_result_error</span></code>:
              this function must be defined by the user.
            </li>
</ul></div>
<p>
          Here is an example of error handling customization where we want to specify
          the result that has to be returned in case of error. We will thus use the
          <code class="computeroutput"><span class="identifier">user_error</span></code> policy, by passing
          as second argument an instance of an overflow_error policy templated with
          <code class="computeroutput"><span class="identifier">user_error</span></code>:
        </p>
<pre class="programlisting"><span class="comment">// First we open the boost::math::policies namespace and define the `user_overflow_error`</span>
<span class="comment">// by making it return the value we want in case of error (-1 here)</span>

<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>
<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>
<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="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;)</span>
<span class="special">{</span> <span class="keyword">return</span> <span class="special">-</span><span class="number">1</span><span class="special">;</span> <span class="special">}</span>
<span class="special">}}}</span>


<span class="comment">// Then we invoke pow and indicate that we want to use the user_error policy</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">policies</span><span class="special">;</span>
<span class="keyword">double</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">pow</span><span class="special">&lt;-</span><span class="number">5</span><span class="special">&gt;(</span><span class="identifier">base</span><span class="special">,</span> <span class="identifier">policy</span><span class="special">&lt;</span><span class="identifier">overflow_error</span><span class="special">&lt;</span><span class="identifier">user_error</span><span class="special">&gt;</span> <span class="special">&gt;());</span>

<span class="comment">// We can now test the returned value and treat the special case if needed:</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">)</span>
<span class="special">{</span>
    <span class="comment">// there was an error, do something...</span>
<span class="special">}</span>
</pre>
<p>
          Another way is to redefine the default <code class="computeroutput"><span class="identifier">overflow_error</span></code>
          policy by using the BOOST_MATH_OVERFLOW_ERROR_POLICY macro. Once the <code class="computeroutput"><span class="identifier">user_overflow_error</span></code> function is defined
          as above, we can achieve the same result like this:
        </p>
<pre class="programlisting"><span class="comment">// Redefine the default error_overflow policy</span>
<span class="preprocessor">#define</span> <span class="identifier">BOOST_MATH_OVERFLOW_ERROR_POLICY</span> <span class="identifier">user_error</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">special_functions</span><span class="special">/</span><span class="identifier">pow</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>

<span class="comment">// From this point, passing a policy in argument is no longer needed, a call like this one</span>
<span class="comment">// will return -1 in case of error:</span>

<span class="keyword">double</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">pow</span><span class="special">&lt;-</span><span class="number">5</span><span class="special">&gt;(</span><span class="identifier">base</span><span class="special">);</span>
</pre>
<h5>
<a name="math_toolkit.special.powers.ct_pow.h5"></a>
          <span><a name="math_toolkit.special.powers.ct_pow.acknowledgements"></a></span><a class="link" href="ct_pow.html#math_toolkit.special.powers.ct_pow.acknowledgements">Acknowledgements</a>
        </h5>
<p>
          Bruno Lalande submitted this addition to Boost.Math.
        </p>
<p>
          Thanks to Joaqu&#237;n L&#243;pez Mu&#241;oz and Scott McMurray for their help in
improving the implementation.
        </p>
<h5>
<a name="math_toolkit.special.powers.ct_pow.h6"></a>
          <span><a name="math_toolkit.special.powers.ct_pow.references"></a></span><a class="link" href="ct_pow.html#math_toolkit.special.powers.ct_pow.references">References</a>
        </h5>
<p>
          D.E. Knuth, <span class="emphasis"><em>The Art of Computer Programming, Vol. 2: Seminumerical
          Algorithms</em></span>, 2nd ed., Addison-Wesley, Reading, MA, 1981
        </p>
</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 John Maddock, Paul A. Bristow, Hubert Holin, Xiaogang Zhang, Bruno
      Lalande, Johan R&#229;de, Gautam Sewani and Thijs van den Berg<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="hypot.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../powers.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="../sinc.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>