boost/libs/math/doc/html/math_toolkit/brent_minima.html
2018-01-12 21:47:58 +01:00

613 lines
85 KiB
HTML

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Locating Function Minima using Brent's algorithm</title>
<link rel="stylesheet" href="../math.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="Math Toolkit 2.6.0">
<link rel="up" href="../root_finding.html" title="Chapter&#160;8.&#160;Root Finding &amp; Minimization Algorithms">
<link rel="prev" href="bad_roots.html" title="Examples Where Root Finding Goes Wrong">
<link rel="next" href="root_comparison.html" title="Comparison of Root Finding Algorithms">
</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="bad_roots.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../root_finding.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="root_comparison.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="math_toolkit.brent_minima"></a><a class="link" href="brent_minima.html" title="Locating Function Minima using Brent's algorithm">Locating Function Minima using
Brent's algorithm</a>
</h2></div></div></div>
<h5>
<a name="math_toolkit.brent_minima.h0"></a>
<span class="phrase"><a name="math_toolkit.brent_minima.synopsis"></a></span><a class="link" href="brent_minima.html#math_toolkit.brent_minima.synopsis">Synopsis</a>
</h5>
<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">tools</span><span class="special">/</span><span class="identifier">minima</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<pre class="programlisting"><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">T</span><span class="special">&gt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">brent_find_minima</span><span class="special">(</span><span class="identifier">F</span> <span class="identifier">f</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">min</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">max</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">bits</span><span class="special">);</span>
<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">T</span><span class="special">&gt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">brent_find_minima</span><span class="special">(</span><span class="identifier">F</span> <span class="identifier">f</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">min</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">max</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">bits</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&amp;</span> <span class="identifier">max_iter</span><span class="special">);</span>
</pre>
<h5>
<a name="math_toolkit.brent_minima.h1"></a>
<span class="phrase"><a name="math_toolkit.brent_minima.description"></a></span><a class="link" href="brent_minima.html#math_toolkit.brent_minima.description">Description</a>
</h5>
<p>
These two functions locate the minima of the continuous function <span class="emphasis"><em>f</em></span>
using <a href="http://en.wikipedia.org/wiki/Brent%27s_method" target="_top">Brent's method</a>:
specifically it uses quadratic interpolation to locate the minima, or if that
fails, falls back to a <a href="http://en.wikipedia.org/wiki/Golden_section_search" target="_top">golden-section
search</a>.
</p>
<p>
<span class="bold"><strong>Parameters</strong></span>
</p>
<div class="variablelist">
<p class="title"><b></b></p>
<dl class="variablelist">
<dt><span class="term">f</span></dt>
<dd><p>
The function to minimise: a function object (functor) that should be
smooth over the range <span class="emphasis"><em>[min, max]</em></span>, with no maxima
occurring in that interval.
</p></dd>
<dt><span class="term">min</span></dt>
<dd><p>
The lower endpoint of the range in which to search for the minima.
</p></dd>
<dt><span class="term">max</span></dt>
<dd><p>
The upper endpoint of the range in which to search for the minima.
</p></dd>
<dt><span class="term">bits</span></dt>
<dd><p>
The number of bits precision to which the minima should be found.<br>
Note that in principle, the minima can not be located to greater accuracy
than the square root of machine epsilon (for 64-bit double, sqrt(1e-16)&#8773;1e-8),
therefore the value of <span class="emphasis"><em>bits</em></span> will be ignored if it's
greater than half the number of bits in the mantissa of T.
</p></dd>
<dt><span class="term">max_iter</span></dt>
<dd><p>
The maximum number of iterations to use in the algorithm, if not provided
the algorithm will just keep on going until the minima is found.
</p></dd>
</dl>
</div>
<p>
<span class="bold"><strong>Returns:</strong></span>
</p>
<p>
A <code class="computeroutput"><span class="identifier">pair</span></code> of type T containing
the value of the abscissa at the minima and the value of <span class="emphasis"><em>f(x)</em></span>
at the minima.
</p>
<div class="tip"><table border="0" summary="Tip">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../doc/src/images/tip.png"></td>
<th align="left">Tip</th>
</tr>
<tr><td align="left" valign="top">
<p>
Defining BOOST_MATH_INSTRUMENT will show some parameters, for example:
</p>
<pre class="programlisting"><span class="identifier">Type</span> <span class="identifier">T</span> <span class="identifier">is</span> <span class="keyword">double</span>
<span class="identifier">bits</span> <span class="special">=</span> <span class="number">24</span><span class="special">,</span> <span class="identifier">maximum</span> <span class="number">26</span>
<span class="identifier">tolerance</span> <span class="special">=</span> <span class="number">1.19209289550781e-007</span>
<span class="identifier">seeking</span> <span class="identifier">minimum</span> <span class="identifier">in</span> <span class="identifier">range</span> <span class="identifier">min</span><span class="special">-</span><span class="number">4</span> <span class="identifier">to</span> <span class="number">1.33333333333333</span>
<span class="identifier">maximum</span> <span class="identifier">iterations</span> <span class="number">18446744073709551615</span>
<span class="number">10</span> <span class="identifier">iterations</span><span class="special">.</span>
</pre>
</td></tr>
</table></div>
<h5>
<a name="math_toolkit.brent_minima.h2"></a>
<span class="phrase"><a name="math_toolkit.brent_minima.example"></a></span><a class="link" href="brent_minima.html#math_toolkit.brent_minima.example">Brent
Minimisation Example</a>
</h5>
<p>
As a demonstration, we replicate this <a href="http://en.wikipedia.org/wiki/Brent%27s_method#Example" target="_top">Wikipedia
example</a> minimising the function <span class="emphasis"><em>y= (x+3)(x-1)<sup>2</sup></em></span>.
</p>
<p>
It is obvious from the equation and the plot that there is a minimum at exactly
one and the value of the function at one is exactly zero.
</p>
<div class="tip"><table border="0" summary="Tip">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../doc/src/images/tip.png"></td>
<th align="left">Tip</th>
</tr>
<tr><td align="left" valign="top"><p>
This observation shows that an analytical or <a href="http://en.wikipedia.org/wiki/Closed-form_expression" target="_top">Closed-form
expression</a> solution always beats brute-force hands-down for both
speed and precision.
</p></td></tr>
</table></div>
<p>
<span class="inlinemediaobject"><img src="../../graphs/brent_test_function_1.svg" align="middle"></span>
</p>
<p>
First an include is needed:
</p>
<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">tools</span><span class="special">/</span><span class="identifier">minima</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<p>
This function is encoded in C++ as function object (functor) using <code class="computeroutput"><span class="keyword">double</span></code> precision thus:
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">funcdouble</span>
<span class="special">{</span>
<span class="keyword">double</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">double</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">)</span>
<span class="special">{</span> <span class="comment">//</span>
<span class="keyword">return</span> <span class="special">(</span><span class="identifier">x</span> <span class="special">+</span> <span class="number">3</span><span class="special">)</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">x</span> <span class="special">-</span> <span class="number">1</span><span class="special">)</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">x</span> <span class="special">-</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// (x + 3)(x - 1)^2</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
The Brent function is conveniently accessed through a <code class="computeroutput"><span class="keyword">using</span></code>
statement (noting sub-namespace <code class="computeroutput"><span class="special">::</span><span class="identifier">tools</span></code>).
</p>
<p>
The search minimum and maximum are chosen as -4 to 4/3 (as in the Wikipedia
example).
</p>
<div class="tip"><table border="0" summary="Tip">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../doc/src/images/tip.png"></td>
<th align="left">Tip</th>
</tr>
<tr><td align="left" valign="top"><p>
S A Stage (reference 6) reports that the Brent algorithm is <span class="emphasis"><em>slow
to start, but fast to converge</em></span>, so choosing a tight min-max range
is good.
</p></td></tr>
</table></div>
<p>
For simplicity, we set the precision parameter <code class="computeroutput"><span class="identifier">bits</span></code>
to <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="keyword">double</span><span class="special">&gt;::</span><span class="identifier">digits</span></code>, which is effectively the maximum
possible i.e. <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="keyword">double</span><span class="special">&gt;::</span><span class="identifier">digits</span></code>/2. Nor do we provide a maximum iterations
parameter <code class="computeroutput"><span class="identifier">max_iter</span></code>, (perhaps
unwidely), so the function will iterate until it finds a minimum.
</p>
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">bits</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="keyword">double</span><span class="special">&gt;::</span><span class="identifier">digits</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">brent_find_minima</span><span class="special">(</span><span class="identifier">funcdouble</span><span class="special">(),</span> <span class="special">-</span><span class="number">4.</span><span class="special">,</span> <span class="number">4.</span> <span class="special">/</span> <span class="number">3</span><span class="special">,</span> <span class="identifier">bits</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">precision</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="keyword">double</span><span class="special">&gt;::</span><span class="identifier">digits10</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"x at minimum = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">first</span> <span class="special">&lt;&lt;</span> <span class="string">", f("</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">first</span> <span class="special">&lt;&lt;</span> <span class="string">") = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">second</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// x at minimum = 1.00000000112345, f(1.00000000112345) = 5.04852568272458e-018</span>
</pre>
<p>
The resulting <a href="http://en.cppreference.com/w/cpp/utility/pair" target="_top">std::pair</a>
contains the minimum close to one and the minimum value close to zero.
</p>
<pre class="programlisting"><span class="identifier">x</span> <span class="identifier">at</span> <span class="identifier">minimum</span> <span class="special">=</span> <span class="number">1.00000000112345</span><span class="special">,</span> <span class="identifier">f</span><span class="special">(</span><span class="number">1.00000000112345</span><span class="special">)</span> <span class="special">=</span> <span class="number">5.04852568272458e-018</span>
</pre>
<p>
The differences from the expected <span class="emphasis"><em>one</em></span> and <span class="emphasis"><em>zero</em></span>
are less than the uncertainty (for <code class="computeroutput"><span class="keyword">double</span></code>)
1.5e-008 calculated from <code class="computeroutput"><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="keyword">double</span><span class="special">&gt;::</span><span class="identifier">digits</span><span class="special">)</span> <span class="special">==</span> <span class="number">53</span></code>.
</p>
<p>
We can use it like this to check that the two values are close-enough to those
expected,
</p>
<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">fpc</span><span class="special">::</span><span class="identifier">is_close_to</span><span class="special">;</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">fpc</span><span class="special">::</span><span class="identifier">is_small</span><span class="special">;</span>
<span class="keyword">double</span> <span class="identifier">uncertainty</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="keyword">double</span><span class="special">&gt;::</span><span class="identifier">digits</span><span class="special">);</span>
<span class="identifier">is_close_to</span><span class="special">(</span><span class="number">1.</span><span class="special">,</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">uncertainty</span><span class="special">);</span>
<span class="identifier">is_small</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">second</span><span class="special">,</span> <span class="identifier">uncertainty</span><span class="special">);</span>
<span class="identifier">x</span> <span class="special">==</span> <span class="number">1</span> <span class="special">(</span><span class="identifier">compared</span> <span class="identifier">to</span> <span class="identifier">uncertainty</span> <span class="number">0.00034527</span><span class="special">)</span> <span class="identifier">is</span> <span class="keyword">true</span>
<span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span> <span class="special">(</span><span class="identifier">compared</span> <span class="identifier">to</span> <span class="identifier">uncertainty</span> <span class="number">0.00034527</span><span class="special">)</span> <span class="identifier">is</span> <span class="keyword">true</span>
</pre>
<p>
It is possible to make this comparison more generally with a templated function,
returning <code class="computeroutput"><span class="keyword">true</span></code> when this criterion
is met, for example:
</p>
<pre class="programlisting"><span class="comment">//</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span> <span class="special">=</span> <span class="keyword">double</span><span class="special">&gt;</span>
<span class="keyword">bool</span> <span class="identifier">close</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">expect</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">got</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">tolerance</span><span class="special">)</span>
<span class="special">{</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">fpc</span><span class="special">::</span><span class="identifier">is_close_to</span><span class="special">;</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">fpc</span><span class="special">::</span><span class="identifier">is_small</span><span class="special">;</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">is_small</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;(</span><span class="identifier">expect</span><span class="special">,</span> <span class="identifier">tolerance</span><span class="special">))</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">is_small</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;(</span><span class="identifier">got</span><span class="special">,</span> <span class="identifier">tolerance</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">else</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">is_close_to</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;(</span><span class="identifier">expect</span><span class="special">,</span> <span class="identifier">got</span><span class="special">,</span> <span class="identifier">tolerance</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
In practical applications, we might want to know how many iterations, and maybe
to limit iterations and perhaps to trade some loss of precision for speed,
for example:
</p>
<pre class="programlisting"><span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span> <span class="identifier">maxit</span> <span class="special">=</span> <span class="number">20</span><span class="special">;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">maxit</span><span class="special">;</span>
<span class="identifier">r</span> <span class="special">=</span> <span class="identifier">brent_find_minima</span><span class="special">(</span><span class="identifier">funcdouble</span><span class="special">(),</span> <span class="special">-</span><span class="number">4.</span><span class="special">,</span> <span class="number">4.</span> <span class="special">/</span> <span class="number">3</span><span class="special">,</span> <span class="identifier">bits</span><span class="special">,</span> <span class="identifier">it</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"x at minimum = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">first</span> <span class="special">&lt;&lt;</span> <span class="string">", f("</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">first</span> <span class="special">&lt;&lt;</span> <span class="string">") = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">second</span>
<span class="special">&lt;&lt;</span> <span class="string">" after "</span> <span class="special">&lt;&lt;</span> <span class="identifier">it</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>
</pre>
<p>
limits to a maximum of 20 iterations (a reasonable estimate for this application,
even for higher precision shown later).
</p>
<p>
The parameter <code class="computeroutput"><span class="identifier">it</span></code> is updated
to return the actual number of iterations (so it may be useful to also keep
a record of the limit in <code class="computeroutput"><span class="identifier">maxit</span></code>).
</p>
<p>
It is neat to avoid showing insignificant digits by computing the number of
decimal digits to display.
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">streamsize</span> <span class="identifier">prec</span> <span class="special">=</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="number">2</span> <span class="special">+</span> <span class="identifier">sqrt</span><span class="special">(</span><span class="identifier">bits</span><span class="special">));</span> <span class="comment">// Number of significant decimal digits.</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Showing "</span> <span class="special">&lt;&lt;</span> <span class="identifier">bits</span> <span class="special">&lt;&lt;</span> <span class="string">" bits precision with "</span> <span class="special">&lt;&lt;</span> <span class="identifier">prec</span>
<span class="special">&lt;&lt;</span> <span class="string">" decimal digits from tolerance "</span> <span class="special">&lt;&lt;</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="keyword">double</span><span class="special">&gt;::</span><span class="identifier">epsilon</span><span class="special">())</span>
<span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">streamsize</span> <span class="identifier">precision</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">precision</span><span class="special">(</span><span class="identifier">prec</span><span class="special">);</span> <span class="comment">// Save.</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"x at minimum = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">first</span> <span class="special">&lt;&lt;</span> <span class="string">", f("</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">first</span> <span class="special">&lt;&lt;</span> <span class="string">") = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">second</span>
<span class="special">&lt;&lt;</span> <span class="string">" after "</span> <span class="special">&lt;&lt;</span> <span class="identifier">it</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>
</pre>
<pre class="programlisting"><span class="identifier">Showing</span> <span class="number">53</span> <span class="identifier">bits</span> <span class="identifier">precision</span> <span class="identifier">with</span> <span class="number">9</span> <span class="identifier">decimal</span> <span class="identifier">digits</span> <span class="identifier">from</span> <span class="identifier">tolerance</span> <span class="number">1.49011611938477e-008</span>
<span class="identifier">x</span> <span class="identifier">at</span> <span class="identifier">minimum</span> <span class="special">=</span> <span class="number">1</span><span class="special">,</span> <span class="identifier">f</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">=</span> <span class="number">5.04852568e-018</span>
</pre>
<p>
We can also half the number of precision bits from 52 to 26.
</p>
<pre class="programlisting"><span class="identifier">bits</span> <span class="special">/=</span> <span class="number">2</span><span class="special">;</span> <span class="comment">// Half digits precision (effective maximum).</span>
<span class="keyword">double</span> <span class="identifier">epsilon_2</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">pow</span><span class="special">&lt;-(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">digits</span><span class="special">/</span><span class="number">2</span> <span class="special">-</span> <span class="number">1</span><span class="special">),</span> <span class="keyword">double</span><span class="special">&gt;(</span><span class="number">2</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Showing "</span> <span class="special">&lt;&lt;</span> <span class="identifier">bits</span> <span class="special">&lt;&lt;</span> <span class="string">" bits precision with "</span> <span class="special">&lt;&lt;</span> <span class="identifier">prec</span>
<span class="special">&lt;&lt;</span> <span class="string">" decimal digits from tolerance "</span> <span class="special">&lt;&lt;</span> <span class="identifier">sqrt</span><span class="special">(</span><span class="identifier">epsilon_2</span><span class="special">)</span>
<span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">streamsize</span> <span class="identifier">precision</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">precision</span><span class="special">(</span><span class="identifier">prec</span><span class="special">);</span> <span class="comment">// Save.</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">maxit</span><span class="special">;</span>
<span class="identifier">r</span> <span class="special">=</span> <span class="identifier">brent_find_minima</span><span class="special">(</span><span class="identifier">funcdouble</span><span class="special">(),</span> <span class="special">-</span><span class="number">4.</span><span class="special">,</span> <span class="number">4.</span> <span class="special">/</span> <span class="number">3</span><span class="special">,</span> <span class="identifier">bits</span><span class="special">,</span> <span class="identifier">it</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"x at minimum = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">first</span> <span class="special">&lt;&lt;</span> <span class="string">", f("</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">first</span> <span class="special">&lt;&lt;</span> <span class="string">") = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">second</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">it</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>
</pre>
<p>
showing no change in the result and no change in the number of iterations,
as expected.
</p>
<p>
It is only if we reduce the precision to a quarter, specifying only 13 precision
bits
</p>
<pre class="programlisting"><span class="identifier">bits</span> <span class="special">/=</span> <span class="number">2</span><span class="special">;</span> <span class="comment">// Quarter precision.</span>
<span class="keyword">double</span> <span class="identifier">epsilon_4</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">pow</span><span class="special">&lt;-(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">digits</span> <span class="special">/</span> <span class="number">4</span> <span class="special">-</span> <span class="number">1</span><span class="special">),</span> <span class="keyword">double</span><span class="special">&gt;(</span><span class="number">2</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Showing "</span> <span class="special">&lt;&lt;</span> <span class="identifier">bits</span> <span class="special">&lt;&lt;</span> <span class="string">" bits precision with "</span> <span class="special">&lt;&lt;</span> <span class="identifier">prec</span>
<span class="special">&lt;&lt;</span> <span class="string">" decimal digits from tolerance "</span> <span class="special">&lt;&lt;</span> <span class="identifier">sqrt</span><span class="special">(</span><span class="identifier">epsilon_4</span><span class="special">)</span>
<span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">streamsize</span> <span class="identifier">precision</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">precision</span><span class="special">(</span><span class="identifier">prec</span><span class="special">);</span> <span class="comment">// Save.</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">maxit</span><span class="special">;</span>
<span class="identifier">r</span> <span class="special">=</span> <span class="identifier">brent_find_minima</span><span class="special">(</span><span class="identifier">funcdouble</span><span class="special">(),</span> <span class="special">-</span><span class="number">4.</span><span class="special">,</span> <span class="number">4.</span> <span class="special">/</span> <span class="number">3</span><span class="special">,</span> <span class="identifier">bits</span><span class="special">,</span> <span class="identifier">it</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"x at minimum = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">first</span> <span class="special">&lt;&lt;</span> <span class="string">", f("</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">first</span> <span class="special">&lt;&lt;</span> <span class="string">") = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">second</span>
<span class="special">&lt;&lt;</span> <span class="string">", after "</span> <span class="special">&lt;&lt;</span> <span class="identifier">it</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>
</pre>
<p>
that we reduce the number of iterations from 10 to 7 and the result significantly
differing from <span class="emphasis"><em>one</em></span> and <span class="emphasis"><em>zero</em></span>.
</p>
<pre class="programlisting"><span class="identifier">Showing</span> <span class="number">13</span> <span class="identifier">bits</span> <span class="identifier">precision</span> <span class="identifier">with</span> <span class="number">9</span> <span class="identifier">decimal</span> <span class="identifier">digits</span> <span class="identifier">from</span> <span class="identifier">tolerance</span> <span class="number">0.015625</span>
<span class="identifier">x</span> <span class="identifier">at</span> <span class="identifier">minimum</span> <span class="special">=</span> <span class="number">0.9999776</span><span class="special">,</span> <span class="identifier">f</span><span class="special">(</span><span class="number">0.9999776</span><span class="special">)</span> <span class="special">=</span> <span class="number">2.0069572e-009</span> <span class="identifier">after</span> <span class="number">7</span> <span class="identifier">iterations</span><span class="special">.</span>
</pre>
<h6>
<a name="math_toolkit.brent_minima.h3"></a>
<span class="phrase"><a name="math_toolkit.brent_minima.template"></a></span><a class="link" href="brent_minima.html#math_toolkit.brent_minima.template">Templating
on floating-point type</a>
</h6>
<p>
If we want to switch the floating-point type, then the functor must be revised.
Since the functor is stateless, the easiest option is to simply make <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code> a
template member function:
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">func</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="keyword">operator</span><span class="special">()(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">)</span>
<span class="special">{</span> <span class="comment">//</span>
<span class="keyword">return</span> <span class="special">(</span><span class="identifier">x</span> <span class="special">+</span> <span class="number">3</span><span class="special">)</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">x</span> <span class="special">-</span> <span class="number">1</span><span class="special">)</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">x</span> <span class="special">-</span> <span class="number">1</span><span class="special">);</span> <span class="comment">//</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
The <code class="computeroutput"><span class="identifier">brent_find_minima</span></code> function
can now be used in template form.
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">precision</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="keyword">long</span> <span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">digits10</span><span class="special">);</span>
<span class="keyword">long</span> <span class="keyword">double</span> <span class="identifier">bracket_min</span> <span class="special">=</span> <span class="special">-</span><span class="number">4.</span><span class="special">;</span>
<span class="keyword">long</span> <span class="keyword">double</span> <span class="identifier">bracket_max</span> <span class="special">=</span> <span class="number">4.</span> <span class="special">/</span> <span class="number">3</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">bits</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="keyword">long</span> <span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">digits</span><span class="special">;</span>
<span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span> <span class="identifier">maxit</span> <span class="special">=</span> <span class="number">20</span><span class="special">;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">maxit</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="keyword">long</span> <span class="keyword">double</span><span class="special">,</span> <span class="keyword">long</span> <span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">brent_find_minima</span><span class="special">(</span><span class="identifier">func</span><span class="special">(),</span> <span class="identifier">bracket_min</span><span class="special">,</span> <span class="identifier">bracket_max</span><span class="special">,</span> <span class="identifier">bits</span><span class="special">,</span> <span class="identifier">it</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"x at minimum = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">first</span> <span class="special">&lt;&lt;</span> <span class="string">", f("</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">first</span> <span class="special">&lt;&lt;</span> <span class="string">") = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">second</span>
<span class="special">&lt;&lt;</span> <span class="string">", after "</span> <span class="special">&lt;&lt;</span> <span class="identifier">it</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>
</pre>
<p>
The form shown uses the floating-point type <code class="computeroutput"><span class="keyword">long</span>
<span class="keyword">double</span></code> by deduction, but it is also
possible to be more explicit, for example:
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="keyword">long</span> <span class="keyword">double</span><span class="special">,</span> <span class="keyword">long</span> <span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">brent_find_minima</span><span class="special">&lt;</span><span class="identifier">func</span><span class="special">,</span> <span class="keyword">long</span> <span class="keyword">double</span><span class="special">&gt;</span>
<span class="special">(</span><span class="identifier">func</span><span class="special">(),</span> <span class="identifier">bracket_min</span><span class="special">,</span> <span class="identifier">bracket_max</span><span class="special">,</span> <span class="identifier">bits</span><span class="special">,</span> <span class="identifier">it</span><span class="special">);</span>
</pre>
<p>
In order to show the use of multiprecision below, it may be convenient to write
a templated function to use this.
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">show_minima</span><span class="special">()</span>
<span class="special">{</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">tools</span><span class="special">::</span><span class="identifier">brent_find_minima</span><span class="special">;</span>
<span class="keyword">try</span>
<span class="special">{</span> <span class="comment">// Always use try'n'catch blocks with Boost.Math to get any error messages.</span>
<span class="keyword">int</span> <span class="identifier">bits</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">digits</span><span class="special">/</span><span class="number">2</span><span class="special">;</span> <span class="comment">// Maximum is digits/2;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">streamsize</span> <span class="identifier">prec</span> <span class="special">=</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="number">2</span> <span class="special">+</span> <span class="identifier">sqrt</span><span class="special">(</span><span class="identifier">bits</span><span class="special">));</span> <span class="comment">// Number of significant decimal digits.</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">streamsize</span> <span class="identifier">precision</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">precision</span><span class="special">(</span><span class="identifier">prec</span><span class="special">);</span> <span class="comment">// Save.</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"\n\nFor type "</span> <span class="special">&lt;&lt;</span> <span class="keyword">typeid</span><span class="special">(</span><span class="identifier">T</span><span class="special">).</span><span class="identifier">name</span><span class="special">()</span>
<span class="special">&lt;&lt;</span> <span class="string">",\n epsilon = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">epsilon</span><span class="special">()</span>
<span class="comment">// &lt;&lt; ", precision of " &lt;&lt; bits &lt;&lt; " bits"</span>
<span class="special">&lt;&lt;</span> <span class="string">",\n the maximum theoretical precision from Brent minimization is "</span> <span class="special">&lt;&lt;</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">T</span><span class="special">&gt;::</span><span class="identifier">epsilon</span><span class="special">())</span>
<span class="special">&lt;&lt;</span> <span class="string">"\n Displaying to std::numeric_limits&lt;T&gt;::digits10 "</span> <span class="special">&lt;&lt;</span> <span class="identifier">prec</span> <span class="special">&lt;&lt;</span> <span class="string">" significant decimal digits."</span>
<span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span> <span class="identifier">maxit</span> <span class="special">=</span> <span class="number">20</span><span class="special">;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">maxit</span><span class="special">;</span>
<span class="comment">// Construct using string, not double, avoids loss of precision.</span>
<span class="comment">//T bracket_min = static_cast&lt;T&gt;("-4");</span>
<span class="comment">//T bracket_max = static_cast&lt;T&gt;("1.3333333333333333333333333333333333333333333333333");</span>
<span class="comment">// Construction from double may cause loss of precision for multiprecision types like cpp_bin_float.</span>
<span class="comment">// but brackets values are good enough for using Brent minimization.</span>
<span class="identifier">T</span> <span class="identifier">bracket_min</span> <span class="special">=</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;(-</span><span class="number">4</span><span class="special">);</span>
<span class="identifier">T</span> <span class="identifier">bracket_max</span> <span class="special">=</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;(</span><span class="number">1.3333333333333333333333333333333333333333333333333</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">brent_find_minima</span><span class="special">&lt;</span><span class="identifier">func</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&gt;(</span><span class="identifier">func</span><span class="special">(),</span> <span class="identifier">bracket_min</span><span class="special">,</span> <span class="identifier">bracket_max</span><span class="special">,</span> <span class="identifier">bits</span><span class="special">,</span> <span class="identifier">it</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">" x at minimum = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">first</span> <span class="special">&lt;&lt;</span> <span class="string">", f("</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">first</span> <span class="special">&lt;&lt;</span> <span class="string">") = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">second</span><span class="special">;</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">it</span> <span class="special">&lt;</span> <span class="identifier">maxit</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">",\n met "</span> <span class="special">&lt;&lt;</span> <span class="identifier">bits</span> <span class="special">&lt;&lt;</span> <span class="string">" bits precision"</span> <span class="special">&lt;&lt;</span> <span class="string">", after "</span> <span class="special">&lt;&lt;</span> <span class="identifier">it</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>
<span class="special">}</span>
<span class="keyword">else</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">",\n did NOT meet "</span> <span class="special">&lt;&lt;</span> <span class="identifier">bits</span> <span class="special">&lt;&lt;</span> <span class="string">" bits precision"</span> <span class="special">&lt;&lt;</span> <span class="string">" after "</span> <span class="special">&lt;&lt;</span> <span class="identifier">it</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>
<span class="special">}</span>
<span class="comment">// Check that result is that expected (compared to theoretical uncertainty).</span>
<span class="identifier">T</span> <span class="identifier">uncertainty</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">T</span><span class="special">&gt;::</span><span class="identifier">epsilon</span><span class="special">());</span>
<span class="comment">//std::cout &lt;&lt; std::boolalpha &lt;&lt; "x == 1 (compared to uncertainty " &lt;&lt; uncertainty &lt;&lt; ") is " &lt;&lt; close(static_cast&lt;T&gt;(1), r.first, uncertainty) &lt;&lt; std::endl;</span>
<span class="comment">//std::cout &lt;&lt; std::boolalpha &lt;&lt; "f(x) == (0 compared to uncertainty " &lt;&lt; uncertainty &lt;&lt; ") is " &lt;&lt; close(static_cast&lt;T&gt;(0), r.second, uncertainty) &lt;&lt; std::endl;</span>
<span class="comment">// Problems with this using multiprecision with expression template on?</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">precision</span><span class="special">(</span><span class="identifier">precision</span><span class="special">);</span> <span class="comment">// Restore.</span>
<span class="special">}</span>
<span class="keyword">catch</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">exception</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span>
<span class="special">{</span> <span class="comment">// Always useful to include try &amp; catch blocks because default policies</span>
<span class="comment">// are to throw exceptions on arguments that cause errors like underflow, overflow.</span>
<span class="comment">// Lacking try &amp; catch blocks, the program will abort without a message below,</span>
<span class="comment">// which may give some helpful clues as to the cause of the exception.</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span>
<span class="string">"\n"</span><span class="string">"Message from thrown exception was:\n "</span> <span class="special">&lt;&lt;</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
<span class="special">}</span> <span class="comment">// void show_minima()</span>
</pre>
<p>
We can use this with all built-in floating-point types, for example
</p>
<pre class="programlisting"><span class="identifier">show_minima</span><span class="special">&lt;</span><span class="keyword">float</span><span class="special">&gt;();</span>
<span class="identifier">show_minima</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;();</span>
<span class="identifier">show_minima</span><span class="special">&lt;</span><span class="keyword">long</span> <span class="keyword">double</span><span class="special">&gt;();</span>
</pre>
<p>
and, on platforms that provide it, a <a href="http://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format" target="_top">128-bit
quad</a> type. (See <a href="../../../../../libs/multiprecision/doc/html/boost_multiprecision/tut/floats/float128.html" target="_top">float128</a>).
</p>
<p>
For this optional include, the build should define the macro BOOST_HAVE_QUADMATH:
</p>
<pre class="programlisting"><span class="preprocessor">#ifdef</span> <span class="identifier">BOOST_HAVE_QUADMATH</span> <span class="comment">// Define only if GCC or Intel and have quadmath.lib or .dll library available.</span>
<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">float128</span><span class="special">;</span>
<span class="preprocessor">#endif</span>
</pre>
<p>
or
</p>
<pre class="programlisting"><span class="comment">// #ifndef _MSC_VER</span>
<span class="preprocessor">#ifdef</span> <span class="identifier">BOOST_HAVE_QUADMATH</span> <span class="comment">// Define only if GCC or Intel and have quadmath.lib or .dll library available.</span>
<span class="identifier">show_minima</span><span class="special">&lt;</span><span class="identifier">float128</span><span class="special">&gt;();</span> <span class="comment">// Needs quadmath_snprintf, sqrtQ, fabsq that are in in quadmath library.</span>
<span class="preprocessor">#endif</span>
</pre>
<h6>
<a name="math_toolkit.brent_minima.h4"></a>
<span class="phrase"><a name="math_toolkit.brent_minima.multiprecision"></a></span><a class="link" href="brent_minima.html#math_toolkit.brent_minima.multiprecision">Multiprecision</a>
</h6>
<p>
If a higher precision than <code class="computeroutput"><span class="keyword">double</span></code>
(or <code class="computeroutput"><span class="keyword">long</span> <span class="keyword">double</span></code>
if that is more precise) is required, then this is easily achieved using <a href="../../../../../libs/multiprecision/doc/html/index.html" target="_top">Boost.Multiprecision</a>
with some includes from
</p>
<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">multiprecision</span><span class="special">/</span><span class="identifier">cpp_dec_float</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <span class="comment">// For decimal boost::multiprecision::cpp_dec_float_50.</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">multiprecision</span><span class="special">/</span><span class="identifier">cpp_bin_float</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <span class="comment">// For binary boost::multiprecision::cpp_bin_float_50;</span>
</pre>
<p>
and some <code class="computeroutput"><span class="identifier">typdef</span></code>s.
</p>
<pre class="programlisting"><span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">cpp_bin_float_50</span><span class="special">;</span> <span class="comment">// binary.</span>
<span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">number</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">cpp_bin_float</span><span class="special">&lt;</span><span class="number">50</span><span class="special">&gt;,</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">et_on</span><span class="special">&gt;</span>
<span class="identifier">cpp_bin_float_50_et_on</span><span class="special">;</span> <span class="comment">// et_on is default so is same as cpp_bin_float_50.</span>
<span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">number</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">cpp_bin_float</span><span class="special">&lt;</span><span class="number">50</span><span class="special">&gt;,</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">et_off</span><span class="special">&gt;</span>
<span class="identifier">cpp_bin_float_50_et_off</span><span class="special">;</span>
<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">cpp_dec_float_50</span><span class="special">;</span> <span class="comment">// decimal.</span>
<span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">number</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">cpp_dec_float</span><span class="special">&lt;</span><span class="number">50</span><span class="special">&gt;,</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">et_on</span><span class="special">&gt;</span> <span class="comment">// et_on is default so is same as cpp_dec_float_50.</span>
<span class="identifier">cpp_dec_float_50_et_on</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">number</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">cpp_dec_float</span><span class="special">&lt;</span><span class="number">50</span><span class="special">&gt;,</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">et_off</span><span class="special">&gt;</span>
<span class="identifier">cpp_dec_float_50_et_off</span><span class="special">;</span>
</pre>
<p>
Using thus
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">precision</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">cpp_bin_float_50</span><span class="special">&gt;::</span><span class="identifier">digits10</span><span class="special">);</span>
<span class="identifier">cpp_bin_float_50</span> <span class="identifier">fpv</span><span class="special">(</span><span class="string">"-1.2345"</span><span class="special">);</span>
<span class="identifier">cpp_bin_float_50</span> <span class="identifier">absv</span><span class="special">;</span>
<span class="identifier">absv</span> <span class="special">=</span> <span class="identifier">fpv</span> <span class="special">&lt;</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">cpp_bin_float_50</span><span class="special">&gt;(</span><span class="number">0</span><span class="special">)</span> <span class="special">?</span> <span class="special">-</span><span class="identifier">fpv</span> <span class="special">:</span> <span class="identifier">fpv</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">fpv</span> <span class="special">&lt;&lt;</span> <span class="char">' '</span> <span class="special">&lt;&lt;</span> <span class="identifier">absv</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">bits</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">cpp_bin_float_50</span><span class="special">&gt;::</span><span class="identifier">digits</span> <span class="special">/</span> <span class="number">2</span> <span class="special">-</span> <span class="number">2</span><span class="special">;</span>
<span class="identifier">cpp_bin_float_50</span> <span class="identifier">bracket_min</span> <span class="special">=</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">cpp_bin_float_50</span><span class="special">&gt;(</span><span class="string">"-4"</span><span class="special">);</span>
<span class="identifier">cpp_bin_float_50</span> <span class="identifier">bracket_max</span> <span class="special">=</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">cpp_bin_float_50</span><span class="special">&gt;(</span><span class="string">"1.3333333333333333333333333333333333333333333333333"</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">bracket_min</span> <span class="special">&lt;&lt;</span> <span class="string">" "</span> <span class="special">&lt;&lt;</span> <span class="identifier">bracket_max</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span> <span class="identifier">maxit</span> <span class="special">=</span> <span class="number">20</span><span class="special">;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">maxit</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">cpp_bin_float_50</span><span class="special">,</span> <span class="identifier">cpp_bin_float_50</span><span class="special">&gt;</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">brent_find_minima</span><span class="special">(</span><span class="identifier">func</span><span class="special">(),</span> <span class="identifier">bracket_min</span><span class="special">,</span> <span class="identifier">bracket_max</span><span class="special">,</span> <span class="identifier">bits</span><span class="special">,</span> <span class="identifier">it</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"x at minimum = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">first</span> <span class="special">&lt;&lt;</span> <span class="string">", f("</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">first</span> <span class="special">&lt;&lt;</span> <span class="string">") = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">second</span>
<span class="comment">// x at minimum = 1, f(1) = 5.04853e-018</span>
<span class="special">&lt;&lt;</span> <span class="string">", after "</span> <span class="special">&lt;&lt;</span> <span class="identifier">it</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>
<span class="identifier">close</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">cpp_bin_float_50</span><span class="special">&gt;(</span><span class="number">1</span><span class="special">),</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">first</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">cpp_bin_float_50</span><span class="special">&gt;::</span><span class="identifier">epsilon</span><span class="special">()));</span>
</pre>
<p>
and with our show function
</p>
<pre class="programlisting"><span class="identifier">show_minima</span><span class="special">&lt;</span><span class="identifier">cpp_bin_float_50_et_on</span><span class="special">&gt;();</span> <span class="comment">//</span>
</pre>
<pre class="programlisting"><span class="identifier">For</span> <span class="identifier">type</span> <span class="keyword">class</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">number</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">backends</span><span class="special">::</span><span class="identifier">cpp_bin_float</span><span class="special">&lt;</span><span class="number">50</span><span class="special">,</span> <span class="number">10</span><span class="special">,</span> <span class="keyword">void</span><span class="special">,</span> <span class="keyword">int</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">&gt;,</span> <span class="number">1</span><span class="special">&gt;,</span>
<span class="identifier">epsilon</span> <span class="special">=</span> <span class="number">5.3455294202e-51</span><span class="special">,</span>
<span class="identifier">the</span> <span class="identifier">maximum</span> <span class="identifier">theoretical</span> <span class="identifier">precision</span> <span class="identifier">from</span> <span class="identifier">Brent</span> <span class="identifier">minimization</span> <span class="identifier">is</span> <span class="number">7.311312755e-26</span>
<span class="identifier">Displaying</span> <span class="identifier">to</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">digits10</span> <span class="number">11</span> <span class="identifier">significant</span> <span class="identifier">decimal</span> <span class="identifier">digits</span><span class="special">.</span>
<span class="identifier">x</span> <span class="identifier">at</span> <span class="identifier">minimum</span> <span class="special">=</span> <span class="number">1</span><span class="special">,</span> <span class="identifier">f</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">=</span> <span class="number">5.6273022713e-58</span><span class="special">,</span>
<span class="identifier">met</span> <span class="number">84</span> <span class="identifier">bits</span> <span class="identifier">precision</span><span class="special">,</span> <span class="identifier">after</span> <span class="number">14</span> <span class="identifier">iterations</span><span class="special">.</span>
</pre>
<pre class="programlisting"><span class="identifier">For</span> <span class="identifier">type</span> <span class="keyword">class</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">number</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">backends</span><span class="special">::</span><span class="identifier">cpp_bin_float</span><span class="special">&lt;</span><span class="number">50</span><span class="special">,</span> <span class="number">10</span><span class="special">,</span> <span class="keyword">void</span><span class="special">,</span> <span class="keyword">int</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">&gt;,</span> <span class="number">1</span><span class="special">&gt;,</span>
</pre>
<div class="tip"><table border="0" summary="Tip">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../doc/src/images/tip.png"></td>
<th align="left">Tip</th>
</tr>
<tr><td align="left" valign="top"><p>
One can usually rely on template argument deduction to avoid specifying the
verbose multiprecision types, but great care in needed with the <span class="emphasis"><em>type
of the values</em></span> provided to avoid confusing the compiler.
</p></td></tr>
</table></div>
<div class="tip"><table border="0" summary="Tip">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../doc/src/images/tip.png"></td>
<th align="left">Tip</th>
</tr>
<tr><td align="left" valign="top"><p>
Using <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">precision</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">digits10</span><span class="special">);</span></code>
or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">precision</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">max_digits10</span><span class="special">);</span></code>
during debugging may be wise because it gives some warning if construction
of multiprecision values involves unintended conversion from <code class="computeroutput"><span class="keyword">double</span></code> by showing trailing zero or random
digits after <a href="http://en.cppreference.com/w/cpp/types/numeric_limits/max_digits10" target="_top">max_digits10</a>,
that is 17 for <code class="computeroutput"><span class="keyword">double</span></code>, digit
18... may be just noise.
</p></td></tr>
</table></div>
<p>
The complete example code is at <a href="../../../example/brent_minimise_example.cpp" target="_top">brent_minimise_example.cpp</a>.
</p>
<h5>
<a name="math_toolkit.brent_minima.h5"></a>
<span class="phrase"><a name="math_toolkit.brent_minima.implementation"></a></span><a class="link" href="brent_minima.html#math_toolkit.brent_minima.implementation">Implementation</a>
</h5>
<p>
This is a reasonably faithful implementation of Brent's algorithm.
</p>
<h5>
<a name="math_toolkit.brent_minima.h6"></a>
<span class="phrase"><a name="math_toolkit.brent_minima.references"></a></span><a class="link" href="brent_minima.html#math_toolkit.brent_minima.references">References</a>
</h5>
<div class="orderedlist"><ol class="orderedlist" type="1">
<li class="listitem">
Brent, R.P. 1973, Algorithms for Minimization without Derivatives, (Englewood
Cliffs, NJ: Prentice-Hall), Chapter 5.
</li>
<li class="listitem">
Numerical Recipes in C, The Art of Scientific Computing, Second Edition,
William H. Press, Saul A. Teukolsky, William T. Vetterling, and Brian P.
Flannery. Cambridge University Press. 1988, 1992.
</li>
<li class="listitem">
An algorithm with guaranteed convergence for finding a zero of a function,
R. P. Brent, The Computer Journal, Vol 44, 1971.
</li>
<li class="listitem">
<a href="http://en.wikipedia.org/wiki/Brent%27s_method" target="_top">Brent's method
in Wikipedia.</a>
</li>
<li class="listitem">
Z. Zhang, An Improvement to the Brent's Method, IJEA, vol. 2, pp. 2 to
26, May 31, 2011. <a href="http://www.cscjournals.org/manuscript/Journals/IJEA/volume2/Issue1/IJEA-7.pdf" target="_top">http://www.cscjournals.org/manuscript/Journals/IJEA/volume2/Issue1/IJEA-7.pdf</a>
</li>
<li class="listitem">
Steven A. Stage, Comments on An Improvement to the Brent's Method (and
comparison of various algorithms) <a href="http://www.cscjournals.org/manuscript/Journals/IJEA/volume4/Issue1/IJEA-33.pdf" target="_top">http://www.cscjournals.org/manuscript/Journals/IJEA/volume4/Issue1/IJEA-33.pdf</a>
Stage concludes that Brent's algorithm is slow to start, but fast to finish
convergence, and has good accuracy.
</li>
</ol></div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2006-2010, 2012-2014, 2017 Nikhar
Agrawal, Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos,
Hubert Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan R&#229;de, Gautam
Sewani, Benjamin Sobotta, Nicholas Thompson, Thijs van den Berg, Daryle Walker
and Xiaogang Zhang<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="bad_roots.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../root_finding.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="root_comparison.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>