• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4<title>Cardinal Cubic B-spline interpolation</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.12.0">
8<link rel="up" href="../interpolation.html" title="Chapter 12. Interpolation">
9<link rel="prev" href="../interpolation.html" title="Chapter 12. Interpolation">
10<link rel="next" href="cardinal_quadratic_b.html" title="Cardinal Quadratic B-spline interpolation">
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="../interpolation.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../interpolation.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="cardinal_quadratic_b.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.cardinal_cubic_b"></a><a class="link" href="cardinal_cubic_b.html" title="Cardinal Cubic B-spline interpolation">Cardinal Cubic B-spline
28    interpolation</a>
29</h2></div></div></div>
30<h4>
31<a name="math_toolkit.cardinal_cubic_b.h0"></a>
32      <span class="phrase"><a name="math_toolkit.cardinal_cubic_b.synopsis"></a></span><a class="link" href="cardinal_cubic_b.html#math_toolkit.cardinal_cubic_b.synopsis">Synopsis</a>
33    </h4>
34<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">interpolators</span><span class="special">/</span><span class="identifier">cardinal_cubic_b_spline</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
35</pre>
36<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">interpolators</span> <span class="special">{</span>
37
38  <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Real</span><span class="special">&gt;</span>
39  <span class="keyword">class</span> <span class="identifier">cardinal_cubic_b_spline</span>
40  <span class="special">{</span>
41  <span class="keyword">public</span><span class="special">:</span>
42
43    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">BidiIterator</span><span class="special">&gt;</span>
44      <span class="identifier">cardinal_cubic_b_spline</span><span class="special">(</span><span class="identifier">BidiIterator</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">BidiIterator</span> <span class="identifier">b</span><span class="special">,</span> <span class="identifier">Real</span> <span class="identifier">left_endpoint</span><span class="special">,</span> <span class="identifier">Real</span> <span class="identifier">step_size</span><span class="special">,</span>
45                     <span class="identifier">Real</span> <span class="identifier">left_endpoint_derivative</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">quiet_NaN</span><span class="special">(),</span>
46                     <span class="identifier">Real</span> <span class="identifier">right_endpoint_derivative</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">quiet_NaN</span><span class="special">());</span>
47      <span class="identifier">cardinal_cubic_b_spline</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Real</span><span class="special">*</span> <span class="keyword">const</span> <span class="identifier">f</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">length</span><span class="special">,</span> <span class="identifier">Real</span> <span class="identifier">left_endpoint</span><span class="special">,</span> <span class="identifier">Real</span> <span class="identifier">step_size</span><span class="special">,</span>
48                     <span class="identifier">Real</span> <span class="identifier">left_endpoint_derivative</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">quiet_NaN</span><span class="special">(),</span>
49                     <span class="identifier">Real</span> <span class="identifier">right_endpoint_derivative</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">quiet_NaN</span><span class="special">());</span>
50
51      <span class="identifier">Real</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Real</span> <span class="identifier">x</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
52
53      <span class="identifier">Real</span> <span class="identifier">prime</span><span class="special">(</span><span class="identifier">Real</span> <span class="identifier">x</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
54
55      <span class="identifier">Real</span> <span class="identifier">double_prime</span><span class="special">(</span><span class="identifier">Real</span> <span class="identifier">x</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
56  <span class="special">};</span>
57
58<span class="special">}}}</span> <span class="comment">// namespaces</span>
59</pre>
60<h4>
61<a name="math_toolkit.cardinal_cubic_b.h1"></a>
62      <span class="phrase"><a name="math_toolkit.cardinal_cubic_b.cardinal_cubic_b_spline_interpol"></a></span><a class="link" href="cardinal_cubic_b.html#math_toolkit.cardinal_cubic_b.cardinal_cubic_b_spline_interpol">Cardinal
63      Cubic B-Spline Interpolation</a>
64    </h4>
65<p>
66      The cardinal cubic <span class="emphasis"><em>B</em></span>-spline class provided by Boost allows
67      fast and accurate interpolation of a function which is known at equally spaced
68      points. The cubic <span class="emphasis"><em>B</em></span>-spline interpolation is numerically
69      stable as it uses compactly supported basis functions constructed via iterative
70      convolution. This is to be contrasted to one-sided power function cubic spline
71      interpolation which is ill-conditioned as the global support of cubic polynomials
72      causes small changes far from the evaluation point to exert a large influence
73      on the calculated value.
74    </p>
75<p>
76      There are many use cases for interpolating a function at equally spaced points.
77      One particularly important example is solving ODEs whose coefficients depend
78      on data determined from experiment or numerical simulation. Since most ODE
79      steppers are adaptive, they must be able to sample the coefficients at arbitrary
80      points; not just at the points we know the values of our function.
81    </p>
82<p>
83      The first two arguments to the constructor are either:
84    </p>
85<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
86<li class="listitem">
87          A pair of bidirectional iterators into the data, or
88        </li>
89<li class="listitem">
90          A pointer to the data, and a length of the data array.
91        </li>
92</ul></div>
93<p>
94      These are then followed by:
95    </p>
96<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
97<li class="listitem">
98          The start of the functions domain,
99        </li>
100<li class="listitem">
101          The step size.
102        </li>
103</ul></div>
104<p>
105      Optionally, you may provide two additional arguments to the constructor, namely
106      the derivative of the function at the left endpoint, and the derivative at
107      the right endpoint. If you do not provide these arguments, they will be estimated
108      using one-sided finite-difference formulas. An example of a valid call to the
109      constructor is
110    </p>
111<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">f</span><span class="special">{</span><span class="number">0.01</span><span class="special">,</span> <span class="special">-</span><span class="number">0.02</span><span class="special">,</span> <span class="number">0.3</span><span class="special">,</span> <span class="number">0.8</span><span class="special">,</span> <span class="number">1.9</span><span class="special">,</span> <span class="special">-</span><span class="number">8.78</span><span class="special">,</span> <span class="special">-</span><span class="number">22.6</span><span class="special">};</span>
112<span class="keyword">double</span> <span class="identifier">t0</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
113<span class="keyword">double</span> <span class="identifier">h</span> <span class="special">=</span> <span class="number">0.01</span><span class="special">;</span>
114<span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">interpolators</span><span class="special">::</span><span class="identifier">cardinal_cubic_b_spline</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">spline</span><span class="special">(</span><span class="identifier">f</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">f</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">t0</span><span class="special">,</span> <span class="identifier">h</span><span class="special">);</span>
115</pre>
116<p>
117      The endpoints are estimated using a one-sided finite-difference formula. If
118      you know the derivative at the endpoint, you may pass it to the constructor
119      via
120    </p>
121<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">interpolators</span><span class="special">::</span><span class="identifier">cardinal_cubic_b_spline</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">spline</span><span class="special">(</span><span class="identifier">f</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">f</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">t0</span><span class="special">,</span> <span class="identifier">h</span><span class="special">,</span> <span class="identifier">a_prime</span><span class="special">,</span> <span class="identifier">b_prime</span><span class="special">);</span>
122</pre>
123<p>
124      To evaluate the interpolant at a point, we simply use
125    </p>
126<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">y</span> <span class="special">=</span> <span class="identifier">spline</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
127</pre>
128<p>
129      and to evaluate the derivative of the interpolant we use
130    </p>
131<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">yp</span> <span class="special">=</span> <span class="identifier">spline</span><span class="special">.</span><span class="identifier">prime</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
132</pre>
133<p>
134      Be aware that the accuracy guarantees on the derivative of the spline are an
135      order lower than the guarantees on the original function, see <a href="http://www.springer.com/us/book/9780387984087" target="_top">Numerical
136      Analysis, Graduate Texts in Mathematics, 181, Rainer Kress</a> for details.
137    </p>
138<p>
139      The last interesting member is the second derivative, evaluated via
140    </p>
141<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">ypp</span> <span class="special">=</span> <span class="identifier">spline</span><span class="special">.</span><span class="identifier">double_prime</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
142</pre>
143<p>
144      The basis functions of the spline are cubic polynomials, so the second derivative
145      is simply linear interpolation. But the interpolation is not constrained by
146      data (you don't pass in the second derivatives), and hence is less accurate
147      than would be naively expected from a linear interpolator. The problem is especially
148      pronounced at the boundaries, where the second derivative is totally unconstrained.
149      Use the second derivative of the cubic B-spline interpolator only in desperation.
150      The quintic <span class="emphasis"><em>B</em></span>-spline interpolator is recommended for cases
151      where second derivatives are needed.
152    </p>
153<h4>
154<a name="math_toolkit.cardinal_cubic_b.h2"></a>
155      <span class="phrase"><a name="math_toolkit.cardinal_cubic_b.complexity_and_performance"></a></span><a class="link" href="cardinal_cubic_b.html#math_toolkit.cardinal_cubic_b.complexity_and_performance">Complexity
156      and Performance</a>
157    </h4>
158<p>
159      The call to the constructor requires ��(<span class="emphasis"><em>n</em></span>) operations, where
160      <span class="emphasis"><em>n</em></span> is the number of points to interpolate. Each call the
161      the interpolant is ��(1) (constant time). On the author's Intel Xeon E3-1230,
162      this takes 21ns as long as the vector is small enough to fit in cache.
163    </p>
164<h4>
165<a name="math_toolkit.cardinal_cubic_b.h3"></a>
166      <span class="phrase"><a name="math_toolkit.cardinal_cubic_b.accuracy"></a></span><a class="link" href="cardinal_cubic_b.html#math_toolkit.cardinal_cubic_b.accuracy">Accuracy</a>
167    </h4>
168<p>
169      Let <span class="emphasis"><em>h</em></span> be the stepsize. If <span class="emphasis"><em>f</em></span> is four-times
170      continuously differentiable, then the interpolant is <span class="emphasis"><em>��(h<sup>4</sup>)</em></span>
171      accurate and the derivative is <span class="emphasis"><em>��(h<sup>3</sup>)</em></span> accurate.
172    </p>
173<h4>
174<a name="math_toolkit.cardinal_cubic_b.h4"></a>
175      <span class="phrase"><a name="math_toolkit.cardinal_cubic_b.testing"></a></span><a class="link" href="cardinal_cubic_b.html#math_toolkit.cardinal_cubic_b.testing">Testing</a>
176    </h4>
177<p>
178      Since the interpolant obeys <span class="serif_italic">s(x<sub>j</sub>) = f(x<sub>j</sub>)</span>
179      at all interpolation points, the tests generate random data and evaluate the
180      interpolant at the interpolation points, validating that equality with the
181      data holds.
182    </p>
183<p>
184      In addition, constant, linear, and quadratic functions are interpolated to
185      ensure that the interpolant behaves as expected.
186    </p>
187<h4>
188<a name="math_toolkit.cardinal_cubic_b.h5"></a>
189      <span class="phrase"><a name="math_toolkit.cardinal_cubic_b.example"></a></span><a class="link" href="cardinal_cubic_b.html#math_toolkit.cardinal_cubic_b.example">Example</a>
190    </h4>
191<p>
192      This example demonstrates how to use the cubic b spline interpolator for regularly
193      spaced data.
194    </p>
195<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">interpolators</span><span class="special">/</span><span class="identifier">cardinal_cubic_b_spline</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
196
197<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
198<span class="special">{</span>
199    <span class="comment">// We begin with an array of samples:</span>
200    <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">v</span><span class="special">(</span><span class="number">500</span><span class="special">);</span>
201    <span class="comment">// And decide on a stepsize:</span>
202    <span class="keyword">double</span> <span class="identifier">step</span> <span class="special">=</span> <span class="number">0.01</span><span class="special">;</span>
203
204    <span class="comment">// Initialize the vector with a function we'd like to interpolate:</span>
205    <span class="keyword">for</span> <span class="special">(</span><span class="identifier">size_t</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="identifier">v</span><span class="special">.</span><span class="identifier">size</span><span class="special">();</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span>
206    <span class="special">{</span>
207        <span class="identifier">v</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">sin</span><span class="special">(</span><span class="identifier">i</span><span class="special">*</span><span class="identifier">step</span><span class="special">);</span>
208    <span class="special">}</span>
209    <span class="comment">// We could define an arbitrary start time, but for now we'll just use 0:</span>
210    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">interpolators</span><span class="special">::</span><span class="identifier">cardinal_cubic_b_spline</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">spline</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">data</span><span class="special">(),</span> <span class="identifier">v</span><span class="special">.</span><span class="identifier">size</span><span class="special">(),</span> <span class="number">0</span> <span class="comment">/* start time */</span><span class="special">,</span> <span class="identifier">step</span><span class="special">);</span>
211
212    <span class="comment">// Now we can evaluate the spline wherever we please.</span>
213    <span class="identifier">std</span><span class="special">::</span><span class="identifier">mt19937</span> <span class="identifier">gen</span><span class="special">;</span>
214    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">random</span><span class="special">::</span><span class="identifier">uniform_real_distribution</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">absissa</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">v</span><span class="special">.</span><span class="identifier">size</span><span class="special">()*</span><span class="identifier">step</span><span class="special">);</span>
215    <span class="keyword">for</span> <span class="special">(</span><span class="identifier">size_t</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="number">10</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span>
216    <span class="special">{</span>
217        <span class="keyword">double</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">absissa</span><span class="special">(</span><span class="identifier">gen</span><span class="special">);</span>
218        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"sin("</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span> <span class="special">&lt;&lt;</span> <span class="string">") = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">sin</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">", spline interpolation gives "</span> <span class="special">&lt;&lt;</span> <span class="identifier">spline</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
219        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"cos("</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span> <span class="special">&lt;&lt;</span> <span class="string">") = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">cos</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">", spline derivative interpolation gives "</span> <span class="special">&lt;&lt;</span> <span class="identifier">spline</span><span class="special">.</span><span class="identifier">prime</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
220    <span class="special">}</span>
221
222    <span class="comment">// The next example is less trivial:</span>
223    <span class="comment">// We will try to figure out when the population of the United States crossed 100 million.</span>
224    <span class="comment">// Since the census is taken every 10 years, the data is equally spaced, so we can use the cubic b spline.</span>
225    <span class="comment">// Data taken from https://en.wikipedia.org/wiki/United_States_Census</span>
226    <span class="comment">// We'll start at the year 1860:</span>
227    <span class="keyword">double</span> <span class="identifier">t0</span> <span class="special">=</span> <span class="number">1860</span><span class="special">;</span>
228    <span class="keyword">double</span> <span class="identifier">time_step</span> <span class="special">=</span> <span class="number">10</span><span class="special">;</span>
229    <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">population</span><span class="special">{</span><span class="number">31443321</span><span class="special">,</span>  <span class="comment">/* 1860 */</span>
230                                   <span class="number">39818449</span><span class="special">,</span>  <span class="comment">/* 1870 */</span>
231                                   <span class="number">50189209</span><span class="special">,</span>  <span class="comment">/* 1880 */</span>
232                                   <span class="number">62947714</span><span class="special">,</span>  <span class="comment">/* 1890 */</span>
233                                   <span class="number">76212168</span><span class="special">,</span>  <span class="comment">/* 1900 */</span>
234                                   <span class="number">92228496</span><span class="special">,</span>  <span class="comment">/* 1910 */</span>
235                                   <span class="number">106021537</span><span class="special">,</span> <span class="comment">/* 1920 */</span>
236                                   <span class="number">122775046</span><span class="special">,</span> <span class="comment">/* 1930 */</span>
237                                   <span class="number">132164569</span><span class="special">,</span> <span class="comment">/* 1940 */</span>
238                                   <span class="number">150697361</span><span class="special">,</span> <span class="comment">/* 1950 */</span>
239                                   <span class="number">179323175</span><span class="special">};/*</span> <span class="number">1960</span> <span class="special">*/</span>
240
241    <span class="comment">// An eyeball estimate indicates that the population crossed 100 million around 1915.</span>
242    <span class="comment">// Let's see what interpolation says:</span>
243    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">interpolators</span><span class="special">::</span><span class="identifier">cardinal_cubic_b_spline</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">p</span><span class="special">(</span><span class="identifier">population</span><span class="special">.</span><span class="identifier">data</span><span class="special">(),</span> <span class="identifier">population</span><span class="special">.</span><span class="identifier">size</span><span class="special">(),</span> <span class="identifier">t0</span><span class="special">,</span> <span class="identifier">time_step</span><span class="special">);</span>
244
245    <span class="comment">// Now create a function which has a zero at p = 100,000,000:</span>
246    <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">t</span><span class="special">){</span> <span class="keyword">return</span> <span class="identifier">p</span><span class="special">(</span><span class="identifier">t</span><span class="special">)</span> <span class="special">-</span> <span class="number">100000000</span><span class="special">;</span> <span class="special">};</span>
247
248    <span class="comment">// Boost includes a bisection algorithm, which is robust, though not as fast as some others</span>
249    <span class="comment">// we provide, but let's try that first.  We need a termination condition for it, which</span>
250    <span class="comment">// takes the two endpoints of the range and returns either true (stop) or false (keep going),</span>
251    <span class="comment">// we could use a predefined one such as boost::math::tools::eps_tolerance&lt;double&gt;, but that</span>
252    <span class="comment">// won't stop until we have full double precision which is overkill, since we just need the</span>
253    <span class="comment">// endpoint to yield the same month.  While we're at it, we'll keep track of the number of</span>
254    <span class="comment">// iterations required too, though this is strictly optional:</span>
255
256    <span class="keyword">auto</span> <span class="identifier">termination</span> <span class="special">=</span> <span class="special">[](</span><span class="keyword">double</span> <span class="identifier">left</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">right</span><span class="special">)</span>
257    <span class="special">{</span>
258       <span class="keyword">double</span> <span class="identifier">left_month</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">round</span><span class="special">((</span><span class="identifier">left</span> <span class="special">-</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">floor</span><span class="special">(</span><span class="identifier">left</span><span class="special">))</span> <span class="special">*</span> <span class="number">12</span> <span class="special">+</span> <span class="number">1</span><span class="special">);</span>
259       <span class="keyword">double</span> <span class="identifier">right_month</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">round</span><span class="special">((</span><span class="identifier">right</span> <span class="special">-</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">floor</span><span class="special">(</span><span class="identifier">right</span><span class="special">))</span> <span class="special">*</span> <span class="number">12</span> <span class="special">+</span> <span class="number">1</span><span class="special">);</span>
260       <span class="keyword">return</span> <span class="special">(</span><span class="identifier">left_month</span> <span class="special">==</span> <span class="identifier">right_month</span><span class="special">)</span> <span class="special">&amp;&amp;</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">floor</span><span class="special">(</span><span class="identifier">left</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">floor</span><span class="special">(</span><span class="identifier">right</span><span class="special">));</span>
261    <span class="special">};</span>
262    <span class="identifier">std</span><span class="special">::</span><span class="identifier">uintmax_t</span> <span class="identifier">iterations</span> <span class="special">=</span> <span class="number">1000</span><span class="special">;</span>
263    <span class="keyword">auto</span> <span class="identifier">result</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">tools</span><span class="special">::</span><span class="identifier">bisect</span><span class="special">(</span><span class="identifier">f</span><span class="special">,</span> <span class="number">1910.0</span><span class="special">,</span> <span class="number">1920.0</span><span class="special">,</span> <span class="identifier">termination</span><span class="special">,</span> <span class="identifier">iterations</span><span class="special">);</span>
264    <span class="keyword">auto</span> <span class="identifier">time</span> <span class="special">=</span> <span class="identifier">result</span><span class="special">.</span><span class="identifier">first</span><span class="special">;</span>  <span class="comment">// termination condition ensures that both endpoints yield the same result</span>
265    <span class="keyword">auto</span> <span class="identifier">month</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">round</span><span class="special">((</span><span class="identifier">time</span> <span class="special">-</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">floor</span><span class="special">(</span><span class="identifier">time</span><span class="special">))*</span><span class="number">12</span>  <span class="special">+</span> <span class="number">1</span><span class="special">);</span>
266    <span class="keyword">auto</span> <span class="identifier">year</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">floor</span><span class="special">(</span><span class="identifier">time</span><span class="special">);</span>
267    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"The population of the United States surpassed 100 million on the "</span><span class="special">;</span>
268    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">month</span> <span class="special">&lt;&lt;</span> <span class="string">"th month of "</span> <span class="special">&lt;&lt;</span> <span class="identifier">year</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>
269    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Found in "</span> <span class="special">&lt;&lt;</span> <span class="identifier">iterations</span> <span class="special">&lt;&lt;</span> <span class="string">" iterations"</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>
270
271    <span class="comment">// Since the cubic B spline offers the first derivative, we could equally have used Newton iterations,</span>
272    <span class="comment">// this takes "number of bits correct" as a termination condition - 20 should be plenty for what we need,</span>
273    <span class="comment">// and once again, we track how many iterations are taken:</span>
274
275    <span class="keyword">auto</span> <span class="identifier">f_n</span> <span class="special">=</span> <span class="special">[=](</span><span class="keyword">double</span> <span class="identifier">t</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_pair</span><span class="special">(</span><span class="identifier">p</span><span class="special">(</span><span class="identifier">t</span><span class="special">)</span> <span class="special">-</span> <span class="number">100000000</span><span class="special">,</span> <span class="identifier">p</span><span class="special">.</span><span class="identifier">prime</span><span class="special">(</span><span class="identifier">t</span><span class="special">));</span> <span class="special">};</span>
276    <span class="identifier">iterations</span> <span class="special">=</span> <span class="number">1000</span><span class="special">;</span>
277    <span class="identifier">time</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">tools</span><span class="special">::</span><span class="identifier">newton_raphson_iterate</span><span class="special">(</span><span class="identifier">f_n</span><span class="special">,</span> <span class="number">1910.0</span><span class="special">,</span> <span class="number">1900.0</span><span class="special">,</span> <span class="number">2000.0</span><span class="special">,</span> <span class="number">20</span><span class="special">,</span> <span class="identifier">iterations</span><span class="special">);</span>
278    <span class="identifier">month</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">round</span><span class="special">((</span><span class="identifier">time</span> <span class="special">-</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">floor</span><span class="special">(</span><span class="identifier">time</span><span class="special">))*</span><span class="number">12</span>  <span class="special">+</span> <span class="number">1</span><span class="special">);</span>
279    <span class="identifier">year</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">floor</span><span class="special">(</span><span class="identifier">time</span><span class="special">);</span>
280    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"The population of the United States surpassed 100 million on the "</span><span class="special">;</span>
281    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">month</span> <span class="special">&lt;&lt;</span> <span class="string">"th month of "</span> <span class="special">&lt;&lt;</span> <span class="identifier">year</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>
282    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Found in "</span> <span class="special">&lt;&lt;</span> <span class="identifier">iterations</span> <span class="special">&lt;&lt;</span> <span class="string">" iterations"</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>
283
284<span class="special">}</span>
285</pre>
286<pre class="programlisting"><span class="identifier">Program</span> <span class="identifier">output</span> <span class="identifier">is</span><span class="special">:</span>
287</pre>
288<pre class="programlisting">sin(4.07362) = -0.802829, spline interpolation gives - 0.802829
289cos(4.07362) = -0.596209, spline derivative interpolation gives - 0.596209
290sin(0.677385) = 0.626758, spline interpolation gives 0.626758
291cos(0.677385) = 0.779214, spline derivative interpolation gives 0.779214
292sin(4.52896) = -0.983224, spline interpolation gives - 0.983224
293cos(4.52896) = -0.182402, spline derivative interpolation gives - 0.182402
294sin(4.17504) = -0.85907, spline interpolation gives - 0.85907
295cos(4.17504) = -0.511858, spline derivative interpolation gives - 0.511858
296sin(0.634934) = 0.593124, spline interpolation gives 0.593124
297cos(0.634934) = 0.805111, spline derivative interpolation gives 0.805111
298sin(4.84434) = -0.991307, spline interpolation gives - 0.991307
299cos(4.84434) = 0.131567, spline derivative interpolation gives 0.131567
300sin(4.56688) = -0.989432, spline interpolation gives - 0.989432
301cos(4.56688) = -0.144997, spline derivative interpolation gives - 0.144997
302sin(1.10517) = 0.893541, spline interpolation gives 0.893541
303cos(1.10517) = 0.448982, spline derivative interpolation gives 0.448982
304sin(3.1618) = -0.0202022, spline interpolation gives - 0.0202022
305cos(3.1618) = -0.999796, spline derivative interpolation gives - 0.999796
306sin(1.54084) = 0.999551, spline interpolation gives 0.999551
307cos(1.54084) = 0.0299566, spline derivative interpolation gives 0.0299566
308The population of the United States surpassed 100 million on the 11th month of 1915
309Found in 12 iterations
310The population of the United States surpassed 100 million on the 11th month of 1915
311Found in 3 iterations
312</pre>
313</div>
314<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
315<td align="left"></td>
316<td align="right"><div class="copyright-footer">Copyright © 2006-2019 Nikhar
317      Agrawal, Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos,
318      Hubert Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Matthew Pulver, Johan
319      Råde, Gautam Sewani, Benjamin Sobotta, Nicholas Thompson, Thijs van den Berg,
320      Daryle Walker and Xiaogang Zhang<p>
321        Distributed under the Boost Software License, Version 1.0. (See accompanying
322        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>)
323      </p>
324</div></td>
325</tr></table>
326<hr>
327<div class="spirit-nav">
328<a accesskey="p" href="../interpolation.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../interpolation.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="cardinal_quadratic_b.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
329</div>
330</body>
331</html>
332