trapezoidal.html 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
  4. <title>Trapezoidal Quadrature</title>
  5. <link rel="stylesheet" href="../math.css" type="text/css">
  6. <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
  7. <link rel="home" href="../index.html" title="Math Toolkit 2.11.0">
  8. <link rel="up" href="../quadrature.html" title="Chapter&#160;13.&#160;Quadrature and Differentiation">
  9. <link rel="prev" href="../quadrature.html" title="Chapter&#160;13.&#160;Quadrature and Differentiation">
  10. <link rel="next" href="gauss.html" title="Gauss-Legendre quadrature">
  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="../quadrature.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../quadrature.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="gauss.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
  24. </div>
  25. <div class="section">
  26. <div class="titlepage"><div><div><h2 class="title" style="clear: both">
  27. <a name="math_toolkit.trapezoidal"></a><a class="link" href="trapezoidal.html" title="Trapezoidal Quadrature">Trapezoidal Quadrature</a>
  28. </h2></div></div></div>
  29. <h4>
  30. <a name="math_toolkit.trapezoidal.h0"></a>
  31. <span class="phrase"><a name="math_toolkit.trapezoidal.synopsis"></a></span><a class="link" href="trapezoidal.html#math_toolkit.trapezoidal.synopsis">Synopsis</a>
  32. </h4>
  33. <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">quadrature</span><span class="special">/</span><span class="identifier">trapezoidal</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  34. <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">quadrature</span> <span class="special">{</span>
  35. <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Real</span><span class="special">&gt;</span>
  36. <span class="keyword">auto</span> <span class="identifier">trapezoidal</span><span class="special">(</span><span class="identifier">F</span> <span class="identifier">f</span><span class="special">,</span> <span class="identifier">Real</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">Real</span> <span class="identifier">b</span><span class="special">,</span>
  37. <span class="identifier">Real</span> <span class="identifier">tol</span> <span class="special">=</span> <span class="identifier">sqrt</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">Real</span><span class="special">&gt;::</span><span class="identifier">epsilon</span><span class="special">()),</span>
  38. <span class="identifier">size_t</span> <span class="identifier">max_refinements</span> <span class="special">=</span> <span class="number">12</span><span class="special">,</span>
  39. <span class="identifier">Real</span><span class="special">*</span> <span class="identifier">error_estimate</span> <span class="special">=</span> <span class="keyword">nullptr</span><span class="special">,</span>
  40. <span class="identifier">Real</span><span class="special">*</span> <span class="identifier">L1</span> <span class="special">=</span> <span class="keyword">nullptr</span><span class="special">);</span>
  41. <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Real</span><span class="special">,</span> <span class="keyword">class</span> <a class="link" href="../policy.html" title="Chapter&#160;20.&#160;Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&gt;</span>
  42. <span class="keyword">auto</span> <span class="identifier">trapezoidal</span><span class="special">(</span><span class="identifier">F</span> <span class="identifier">f</span><span class="special">,</span> <span class="identifier">Real</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">Real</span> <span class="identifier">b</span><span class="special">,</span> <span class="identifier">Real</span> <span class="identifier">tol</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">max_refinements</span><span class="special">,</span>
  43. <span class="identifier">Real</span><span class="special">*</span> <span class="identifier">error_estimate</span><span class="special">,</span> <span class="identifier">Real</span><span class="special">*</span> <span class="identifier">L1</span><span class="special">,</span> <span class="keyword">const</span> <a class="link" href="../policy.html" title="Chapter&#160;20.&#160;Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&amp;</span> <span class="identifier">pol</span><span class="special">);</span>
  44. <span class="special">}}}</span> <span class="comment">// namespaces</span>
  45. </pre>
  46. <h4>
  47. <a name="math_toolkit.trapezoidal.h1"></a>
  48. <span class="phrase"><a name="math_toolkit.trapezoidal.description"></a></span><a class="link" href="trapezoidal.html#math_toolkit.trapezoidal.description">Description</a>
  49. </h4>
  50. <p>
  51. The functional <code class="computeroutput"><span class="identifier">trapezoidal</span></code>
  52. calculates the integral of a function <span class="emphasis"><em>f</em></span> using the surprisingly
  53. simple trapezoidal rule. If we assume only that the integrand is twice continuously
  54. differentiable, we can prove that the error of the composite trapezoidal rule
  55. is &#119926;(h<sup>2</sup>). Hence halving the interval only cuts the error by about a fourth,
  56. which in turn implies that we must evaluate the function many times before
  57. an acceptable accuracy can be achieved.
  58. </p>
  59. <p>
  60. However, the trapezoidal rule has an astonishing property: If the integrand
  61. is periodic, and we integrate it over a period, then the trapezoidal rule converges
  62. faster than any power of the step size <span class="emphasis"><em>h</em></span>. This can be
  63. seen by examination of the <a href="https://en.wikipedia.org/wiki/Euler-Maclaurin_formula" target="_top">Euler-Maclaurin
  64. summation formula</a>, which relates a definite integral to its trapezoidal
  65. sum and error terms proportional to the derivatives of the function at the
  66. endpoints and the Bernoulli numbers. If the derivatives at the endpoints are
  67. the same or vanish, then the error very nearly vanishes. Hence the trapezoidal
  68. rule is essentially optimal for periodic integrands.
  69. </p>
  70. <p>
  71. Other classes of integrands which are integrated efficiently by this method
  72. are the C<sub>0</sub><sup>&#8734;</sup>(&#8733;) <a href="https://en.wikipedia.org/wiki/Bump_function" target="_top">bump
  73. functions</a> and bell-shaped integrals over the infinite interval. For
  74. details, see <a href="http://epubs.siam.org/doi/pdf/10.1137/130932132" target="_top">Trefethen's</a>
  75. SIAM review.
  76. </p>
  77. <p>
  78. In its simplest form, an integration can be performed by the following code
  79. </p>
  80. <pre class="programlisting"><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">quadrature</span><span class="special">::</span><span class="identifier">trapezoidal</span><span class="special">;</span>
  81. <span class="keyword">auto</span> <span class="identifier">f</span> <span class="special">=</span> <span class="special">[](</span><span class="keyword">double</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="number">1</span><span class="special">/(</span><span class="number">5</span> <span class="special">-</span> <span class="number">4</span><span class="special">*</span><span class="identifier">cos</span><span class="special">(</span><span class="identifier">x</span><span class="special">));</span> <span class="special">};</span>
  82. <span class="keyword">double</span> <span class="identifier">I</span> <span class="special">=</span> <span class="identifier">trapezoidal</span><span class="special">(</span><span class="identifier">f</span><span class="special">,</span> <span class="number">0.0</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">constants</span><span class="special">::</span><span class="identifier">two_pi</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;());</span>
  83. </pre>
  84. <p>
  85. The integrand must accept a real number argument, but can return a complex
  86. number. This is useful for contour integrals (which are manifestly periodic)
  87. and high-order numerical differentiation of analytic functions. An example
  88. using the integral definition of the complex Bessel function is shown here:
  89. </p>
  90. <pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">bessel_integrand</span> <span class="special">=</span> <span class="special">[&amp;</span><span class="identifier">n</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">z</span><span class="special">](</span><span class="keyword">double</span> <span class="identifier">theta</span><span class="special">)-&gt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span>
  91. <span class="special">{</span>
  92. <span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">z</span><span class="special">{</span><span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">};</span>
  93. <span class="keyword">using</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cos</span><span class="special">;</span>
  94. <span class="keyword">using</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">sin</span><span class="special">;</span>
  95. <span class="keyword">return</span> <span class="identifier">cos</span><span class="special">(</span><span class="identifier">z</span><span class="special">*</span><span class="identifier">sin</span><span class="special">(</span><span class="identifier">theta</span><span class="special">)</span> <span class="special">-</span> <span class="number">2</span><span class="special">*</span><span class="identifier">theta</span><span class="special">)/</span><span class="identifier">pi</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;();</span>
  96. <span class="special">};</span>
  97. <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">quadrature</span><span class="special">::</span><span class="identifier">trapezoidal</span><span class="special">;</span>
  98. <span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">Jnz</span> <span class="special">=</span> <span class="identifier">trapezoidal</span><span class="special">(</span><span class="identifier">bessel_integrand</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="identifier">pi</span><span class="special">&lt;</span><span class="identifier">Real</span><span class="special">&gt;());</span>
  99. </pre>
  100. <p>
  101. Other special functions which are efficiently evaluated in the complex plane
  102. by trapezoidal quadrature are modified Bessel functions and the complementary
  103. error function. Another application of complex-valued trapezoidal quadrature
  104. is computation of high-order numerical derivatives; see Lyness and Moler for
  105. details.
  106. </p>
  107. <p>
  108. Since the routine is adaptive, step sizes are halved continuously until a tolerance
  109. is reached. In order to control this tolerance, simply call the routine with
  110. an additional argument
  111. </p>
  112. <pre class="programlisting"><span class="keyword">double</span> <span class="identifier">I</span> <span class="special">=</span> <span class="identifier">trapezoidal</span><span class="special">(</span><span class="identifier">f</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="identifier">two_pi</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;(),</span> <span class="number">1e-6</span><span class="special">);</span>
  113. </pre>
  114. <p>
  115. The routine stops when successive estimates of the integral <code class="computeroutput"><span class="identifier">I1</span></code>
  116. and <code class="computeroutput"><span class="identifier">I0</span></code> differ by less than
  117. the tolerance multiplied by the estimated L<sub>1</sub> norm of the function. A good choice
  118. for the tolerance is &#8730;&#949;, which is the default. If the integrand is periodic,
  119. then the number of correct digits should double on each interval halving. Hence,
  120. once the integration routine has estimated that the error is &#8730;&#949;, then the actual
  121. error should be ~&#949;. If the integrand is <span class="bold"><strong>not</strong></span>
  122. periodic, then reducing the error to &#8730;&#949; takes much longer, but is nonetheless
  123. possible without becoming a major performance bug.
  124. </p>
  125. <p>
  126. A question arises as to what to do when successive estimates never pass below
  127. the tolerance threshold. The stepsize would be halved repeatedly, generating
  128. an exponential explosion in function evaluations. As such, you may pass an
  129. optional argument <code class="computeroutput"><span class="identifier">max_refinements</span></code>
  130. which controls how many times the interval may be halved before giving up.
  131. By default, this maximum number of refinement steps is 12, which should never
  132. be hit in double precision unless the function is not periodic. However, for
  133. higher-precision types, it may be of interest to allow the algorithm to compute
  134. more refinements:
  135. </p>
  136. <pre class="programlisting"><span class="identifier">size_t</span> <span class="identifier">max_refinements</span> <span class="special">=</span> <span class="number">15</span><span class="special">;</span>
  137. <span class="keyword">long</span> <span class="keyword">double</span> <span class="identifier">I</span> <span class="special">=</span> <span class="identifier">trapezoidal</span><span class="special">(</span><span class="identifier">f</span><span class="special">,</span> <span class="number">0.0L</span><span class="special">,</span> <span class="identifier">two_pi</span><span class="special">&lt;</span><span class="keyword">long</span> <span class="keyword">double</span><span class="special">&gt;(),</span> <span class="number">1e-9L</span><span class="special">,</span> <span class="identifier">max_refinements</span><span class="special">);</span>
  138. </pre>
  139. <p>
  140. Note that the maximum allowed compute time grows exponentially with <code class="computeroutput"><span class="identifier">max_refinements</span></code>. The routine will not throw
  141. an exception if the maximum refinements is achieved without the requested tolerance
  142. being attained. This is because the value calculated is more often than not
  143. still usable. However, for applications with high-reliability requirements,
  144. the error estimate should be queried. This is achieved by passing additional
  145. pointers into the routine:
  146. </p>
  147. <pre class="programlisting"><span class="keyword">double</span> <span class="identifier">error_estimate</span><span class="special">;</span>
  148. <span class="keyword">double</span> <span class="identifier">L1</span><span class="special">;</span>
  149. <span class="keyword">double</span> <span class="identifier">I</span> <span class="special">=</span> <span class="identifier">trapezoidal</span><span class="special">(</span><span class="identifier">f</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="identifier">two_pi</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;(),</span> <span class="identifier">tolerance</span><span class="special">,</span> <span class="identifier">max_refinements</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">error_estimate</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">L1</span><span class="special">);</span>
  150. <span class="keyword">if</span> <span class="special">(</span><span class="identifier">error_estimate</span> <span class="special">&gt;</span> <span class="identifier">tolerance</span><span class="special">*</span><span class="identifier">L1</span><span class="special">)</span>
  151. <span class="special">{</span>
  152. <span class="keyword">double</span> <span class="identifier">I</span> <span class="special">=</span> <span class="identifier">some_other_quadrature_method</span><span class="special">(</span><span class="identifier">f</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">two_pi</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;());</span>
  153. <span class="special">}</span>
  154. </pre>
  155. <p>
  156. The final argument is the L<sub>1</sub> norm of the integral. This is computed along with
  157. the integral, and is an essential component of the algorithm. First, the L<sub>1</sub> norm
  158. establishes a scale against which the error can be measured. Second, the L<sub>1</sub> norm
  159. can be used to evaluate the stability of the computation. This can be formulated
  160. in a rigorous manner by defining the <span class="bold"><strong>condition number
  161. of summation</strong></span>. The condition number of summation is defined by
  162. </p>
  163. <div class="blockquote"><blockquote class="blockquote"><p>
  164. <span class="serif_italic"><span class="emphasis"><em>&#954;(S<sub>n</sub>) := &#931;<sub>i</sub><sup>n</sup> |x<sub>i</sub>|/|&#931;<sub>i</sub><sup>n</sup> x<sub>i</sub>|</em></span></span>
  165. </p></blockquote></div>
  166. <p>
  167. If this number of ~10<sup>k</sup>, then <span class="emphasis"><em>k</em></span> additional digits are expected
  168. to be lost in addition to digits lost due to floating point rounding error.
  169. As all numerical quadrature methods reduce to summation, their stability is
  170. controlled by the ratio &#8747; |f| dt/|&#8747; f dt |, which is easily seen
  171. to be equivalent to condition number of summation when evaluated numerically.
  172. Hence both the error estimate and the condition number of summation should
  173. be analyzed in applications requiring very high precision and reliability.
  174. </p>
  175. <p>
  176. As an example, we consider evaluation of Bessel functions by trapezoidal quadrature.
  177. The Bessel function of the first kind is defined via
  178. </p>
  179. <div class="blockquote"><blockquote class="blockquote"><p>
  180. <span class="serif_italic"><span class="emphasis"><em>J<sub>n</sub>(x) = 1/2&#928; &#8747;<sub>-&#928;</sub><sup>&#928;</sup> cos(n
  181. t - x sin(t)) dt</em></span></span>
  182. </p></blockquote></div>
  183. <p>
  184. The integrand is periodic, so the Euler-Maclaurin summation formula guarantees
  185. exponential convergence via the trapezoidal quadrature. Without careful consideration,
  186. it seems this would be a very attractive method to compute Bessel functions.
  187. However, we see that for large <span class="emphasis"><em>n</em></span> the integrand oscillates
  188. rapidly, taking on positive and negative values, and hence the trapezoidal
  189. sums become ill-conditioned. In double precision, <span class="emphasis"><em>x = 17</em></span>
  190. and <span class="emphasis"><em>n = 25</em></span> gives a sum which is so poorly conditioned
  191. that zero correct digits are obtained.
  192. </p>
  193. <p>
  194. The final <a class="link" href="../policy.html" title="Chapter&#160;20.&#160;Policies: Controlling Precision, Error Handling etc">Policy</a> argument is optional and can
  195. be used to control the behaviour of the function: how it handles errors, what
  196. level of precision to use etc. Refer to the <a class="link" href="../policy.html" title="Chapter&#160;20.&#160;Policies: Controlling Precision, Error Handling etc">policy documentation
  197. for more details</a>.
  198. </p>
  199. <p>
  200. References:
  201. </p>
  202. <p>
  203. Trefethen, Lloyd N., Weideman, J.A.C., <span class="emphasis"><em>The Exponentially Convergent
  204. Trapezoidal Rule</em></span>, SIAM Review, Vol. 56, No. 3, 2014.
  205. </p>
  206. <p>
  207. Stoer, Josef, and Roland Bulirsch. <span class="emphasis"><em>Introduction to numerical analysis.
  208. Vol. 12.</em></span>, Springer Science &amp; Business Media, 2013.
  209. </p>
  210. <p>
  211. Higham, Nicholas J. <span class="emphasis"><em>Accuracy and stability of numerical algorithms.</em></span>
  212. Society for industrial and applied mathematics, 2002.
  213. </p>
  214. <p>
  215. Lyness, James N., and Cleve B. Moler. <span class="emphasis"><em>Numerical differentiation of
  216. analytic functions.</em></span> SIAM Journal on Numerical Analysis 4.2 (1967):
  217. 202-210.
  218. </p>
  219. <p>
  220. Gil, Amparo, Javier Segura, and Nico M. Temme. <span class="emphasis"><em>Computing special
  221. functions by using quadrature rules.</em></span> Numerical Algorithms 33.1-4
  222. (2003): 265-275.
  223. </p>
  224. </div>
  225. <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
  226. <td align="left"></td>
  227. <td align="right"><div class="copyright-footer">Copyright &#169; 2006-2019 Nikhar
  228. Agrawal, Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos,
  229. Hubert Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Matthew Pulver, Johan
  230. R&#229;de, Gautam Sewani, Benjamin Sobotta, Nicholas Thompson, Thijs van den Berg,
  231. Daryle Walker and Xiaogang Zhang<p>
  232. Distributed under the Boost Software License, Version 1.0. (See accompanying
  233. 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>)
  234. </p>
  235. </div></td>
  236. </tr></table>
  237. <hr>
  238. <div class="spirit-nav">
  239. <a accesskey="p" href="../quadrature.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../quadrature.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="gauss.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
  240. </div>
  241. </body>
  242. </html>