[DEV] add v1.66.0

This commit is contained in:
2018-01-12 21:47:58 +01:00
parent 87059bb1af
commit a97e9ae7d4
49032 changed files with 7668950 additions and 0 deletions

View File

@@ -0,0 +1,311 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Root Finding With Derivatives: Newton-Raphson, Halley &amp; Schr&#246;der</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="roots_noderiv/implementation.html" title="Implementation">
<link rel="next" href="root_finding_examples.html" title="Examples of Root-Finding (with and without derivatives)">
</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="roots_noderiv/implementation.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_finding_examples.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.roots_deriv"></a><a class="link" href="roots_deriv.html" title="Root Finding With Derivatives: Newton-Raphson, Halley &amp; Schr&#246;der">Root Finding With Derivatives:
Newton-Raphson, Halley &amp; Schr&#246;der</a>
</h2></div></div></div>
<h5>
<a name="math_toolkit.roots_deriv.h0"></a>
<span class="phrase"><a name="math_toolkit.roots_deriv.synopsis"></a></span><a class="link" href="roots_deriv.html#math_toolkit.roots_deriv.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">roots</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<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">tools</span> <span class="special">{</span> <span class="comment">// Note namespace boost::math::tools.</span>
<span class="comment">// Newton-Raphson</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">T</span> <span class="identifier">newton_raphson_iterate</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">guess</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">digits</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">T</span> <span class="identifier">newton_raphson_iterate</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">guess</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">digits</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>
<span class="comment">// Halley</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">T</span> <span class="identifier">halley_iterate</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">guess</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">digits</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">T</span> <span class="identifier">halley_iterate</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">guess</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">digits</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>
<span class="comment">// Schr'''&amp;#xf6;'''der</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">T</span> <span class="identifier">schroder_iterate</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">guess</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">digits</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">T</span> <span class="identifier">schroder_iterate</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">guess</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">digits</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>
<span class="special">}}}</span> <span class="comment">// namespaces boost::math::tools.</span>
</pre>
<h5>
<a name="math_toolkit.roots_deriv.h1"></a>
<span class="phrase"><a name="math_toolkit.roots_deriv.description"></a></span><a class="link" href="roots_deriv.html#math_toolkit.roots_deriv.description">Description</a>
</h5>
<p>
These functions all perform iterative root-finding <span class="bold"><strong>using
derivatives</strong></span>:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<code class="computeroutput"><span class="identifier">newton_raphson_iterate</span></code>
performs second-order <a class="link" href="roots_deriv.html#math_toolkit.roots_deriv.newton">Newton-Raphson
iteration</a>.
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">halley_iterate</span></code> and <code class="computeroutput"><span class="identifier">schroder_iterate</span></code> perform third-order
<a class="link" href="roots_deriv.html#math_toolkit.roots_deriv.halley">Halley</a> and <a class="link" href="roots_deriv.html#math_toolkit.roots_deriv.schroder">Schr&#246;der</a> iteration.
</li>
</ul></div>
<p>
The functions all take the same parameters:
</p>
<div class="variablelist">
<p class="title"><b>Parameters of the root finding functions</b></p>
<dl class="variablelist">
<dt><span class="term">F f</span></dt>
<dd>
<p>
Type F must be a callable function object that accepts one parameter
and returns a <a class="link" href="internals/tuples.html" title="Tuples">std::pair,
std::tuple, boost::tuple or boost::fusion::tuple</a>:
</p>
<p>
For second-order iterative method (<a href="http://en.wikipedia.org/wiki/Newton_Raphson" target="_top">Newton
Raphson</a>) the <code class="computeroutput"><span class="identifier">tuple</span></code>
should have <span class="bold"><strong>two</strong></span> elements containing
the evaluation of the function and its first derivative.
</p>
<p>
For the third-order methods (<a href="http://en.wikipedia.org/wiki/Halley%27s_method" target="_top">Halley</a>
and Schr&#246;der) the <code class="computeroutput"><span class="identifier">tuple</span></code>
should have <span class="bold"><strong>three</strong></span> elements containing
the evaluation of the function and its first and second derivatives.
</p>
</dd>
<dt><span class="term">T guess</span></dt>
<dd><p>
The initial starting value. A good guess is crucial to quick convergence!
</p></dd>
<dt><span class="term">T min</span></dt>
<dd><p>
The minimum possible value for the result, this is used as an initial
lower bracket.
</p></dd>
<dt><span class="term">T max</span></dt>
<dd><p>
The maximum possible value for the result, this is used as an initial
upper bracket.
</p></dd>
<dt><span class="term">int digits</span></dt>
<dd><p>
The desired number of binary digits precision.
</p></dd>
<dt><span class="term">uintmax_t&amp; max_iter</span></dt>
<dd><p>
An optional maximum number of iterations to perform. On exit, this is
updated to the actual number of iterations performed.
</p></dd>
</dl>
</div>
<p>
When using these functions you should note that:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Default <code class="computeroutput"><span class="identifier">max_iter</span> <span class="special">=</span>
<span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&gt;::</span><span class="identifier">max</span><span class="special">)()</span></code> is effectively 'iterate for ever'.
</li>
<li class="listitem">
They may be very sensitive to the initial guess, typically they converge
very rapidly if the initial guess has two or three decimal digits correct.
However convergence can be no better than <a class="link" href="roots_noderiv/bisect.html" title="Bisection">bisect</a>,
or in some rare cases, even worse than <a class="link" href="roots_noderiv/bisect.html" title="Bisection">bisect</a>
if the initial guess is a long way from the correct value and the derivatives
are close to zero.
</li>
<li class="listitem">
These functions include special cases to handle zero first (and second
where appropriate) derivatives, and fall back to <a class="link" href="roots_noderiv/bisect.html" title="Bisection">bisect</a>
in this case. However, it is helpful if functor F is defined to return
an arbitrarily small value <span class="emphasis"><em>of the correct sign</em></span> rather
than zero.
</li>
<li class="listitem">
If the derivative at the current best guess for the result is infinite
(or very close to being infinite) then these functions may terminate prematurely.
A large first derivative leads to a very small next step, triggering the
termination condition. Derivative based iteration may not be appropriate
in such cases.
</li>
<li class="listitem">
If the function is 'Really Well Behaved' (is monotonic and has only one
root) the bracket bounds <span class="emphasis"><em>min</em></span> and <span class="emphasis"><em>max</em></span>
may as well be set to the widest limits like zero and <code class="computeroutput"><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</span><span class="special">()</span></code>.
</li>
<li class="listitem">
But if the function more complex and may have more than one root or a pole,
the choice of bounds is protection against jumping out to seek the 'wrong'
root.
</li>
<li class="listitem">
These functions fall back to <a class="link" href="roots_noderiv/bisect.html" title="Bisection">bisect</a>
if the next computed step would take the next value out of bounds. The
bounds are updated after each step to ensure this leads to convergence.
However, a good initial guess backed up by asymptotically-tight bounds
will improve performance no end - rather than relying on <a class="link" href="roots_noderiv/bisect.html" title="Bisection">bisection</a>.
</li>
<li class="listitem">
The value of <span class="emphasis"><em>digits</em></span> is crucial to good performance
of these functions, if it is set too high then at best you will get one
extra (unnecessary) iteration, and at worst the last few steps will proceed
by <a class="link" href="roots_noderiv/bisect.html" title="Bisection">bisection</a>.
Remember that the returned value can never be more accurate than <span class="emphasis"><em>f(x)</em></span>
can be evaluated, and that if <span class="emphasis"><em>f(x)</em></span> suffers from cancellation
errors as it tends to zero then the computed steps will be effectively
random. The value of <span class="emphasis"><em>digits</em></span> should be set so that
iteration terminates before this point: remember that for second and third
order methods the number of correct digits in the result is increasing
quite substantially with each iteration, <span class="emphasis"><em>digits</em></span> should
be set by experiment so that the final iteration just takes the next value
into the zone where <span class="emphasis"><em>f(x)</em></span> becomes inaccurate. A good
starting point for <span class="emphasis"><em>digits</em></span> would be 0.6*D for Newton
and 0.4*D for Halley or Shr&#246;der iteration, where D is <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">digits</span></code>.
</li>
<li class="listitem">
If you need some diagnostic output to see what is going on, you can <code class="computeroutput"><span class="preprocessor">#define</span> <span class="identifier">BOOST_MATH_INSTRUMENT</span></code>
before the <code class="computeroutput"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">tools</span><span class="special">/</span><span class="identifier">roots</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code>, and also ensure that display of all
the significant digits with <code class="computeroutput"> <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></code>: or even possibly significant digits with
<code class="computeroutput"> <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">max_digits10</span><span class="special">)</span></code>:
but be warned, this may produce copious output!
</li>
<li class="listitem">
Finally: you may well be able to do better than these functions by hand-coding
the heuristics used so that they are tailored to a specific function. You
may also be able to compute the ratio of derivatives used by these methods
more efficiently than computing the derivatives themselves. As ever, algebraic
simplification can be a big win.
</li>
</ul></div>
<h5>
<a name="math_toolkit.roots_deriv.h2"></a>
<span class="phrase"><a name="math_toolkit.roots_deriv.newton"></a></span><a class="link" href="roots_deriv.html#math_toolkit.roots_deriv.newton">Newton
Raphson Method</a>
</h5>
<p>
Given an initial guess <span class="emphasis"><em>x0</em></span> the subsequent values are computed
using:
</p>
<p>
<span class="inlinemediaobject"><img src="../../equations/roots1.svg"></span>
</p>
<p>
Out of bounds steps revert to <a class="link" href="roots_noderiv/bisect.html" title="Bisection">bisection</a>
of the current bounds.
</p>
<p>
Under ideal conditions, the number of correct digits doubles with each iteration.
</p>
<h5>
<a name="math_toolkit.roots_deriv.h3"></a>
<span class="phrase"><a name="math_toolkit.roots_deriv.halley"></a></span><a class="link" href="roots_deriv.html#math_toolkit.roots_deriv.halley">Halley's
Method</a>
</h5>
<p>
Given an initial guess <span class="emphasis"><em>x0</em></span> the subsequent values are computed
using:
</p>
<p>
<span class="inlinemediaobject"><img src="../../equations/roots2.svg"></span>
</p>
<p>
Over-compensation by the second derivative (one which would proceed in the
wrong direction) causes the method to revert to a Newton-Raphson step.
</p>
<p>
Out of bounds steps revert to bisection of the current bounds.
</p>
<p>
Under ideal conditions, the number of correct digits trebles with each iteration.
</p>
<h5>
<a name="math_toolkit.roots_deriv.h4"></a>
<span class="phrase"><a name="math_toolkit.roots_deriv.schroder"></a></span><a class="link" href="roots_deriv.html#math_toolkit.roots_deriv.schroder">Schr&#246;der's
Method</a>
</h5>
<p>
Given an initial guess x0 the subsequent values are computed using:
</p>
<p>
<span class="inlinemediaobject"><img src="../../equations/roots3.svg"></span>
</p>
<p>
Over-compensation by the second derivative (one which would proceed in the
wrong direction) causes the method to revert to a Newton-Raphson step. Likewise
a Newton step is used whenever that Newton step would change the next value
by more than 10%.
</p>
<p>
Out of bounds steps revert to <a href="https://en.wikipedia.org/wiki/Bisection" target="_top">bisection</a>
of the current bounds.
</p>
<p>
Under ideal conditions, the number of correct digits trebles with each iteration.
</p>
<p>
This is Schr&#246;der's general result (equation 18 from <a href="http://drum.lib.umd.edu/handle/1903/577" target="_top">Stewart,
G. W. "On Infinitely Many Algorithms for Solving Equations." English
translation of Schr&#246;der's original paper. College Park, MD: University of Maryland,
Institute for Advanced Computer Studies, Department of Computer Science, 1993</a>.)
</p>
<p>
This method guarantees at least quadratic convergence (the same as Newton's
method), and is known to work well in the presence of multiple roots: something
that neither Newton nor Halley can do.
</p>
<h5>
<a name="math_toolkit.roots_deriv.h5"></a>
<span class="phrase"><a name="math_toolkit.roots_deriv.examples"></a></span><a class="link" href="roots_deriv.html#math_toolkit.roots_deriv.examples">Examples</a>
</h5>
<p>
See <a class="link" href="root_finding_examples.html" title="Examples of Root-Finding (with and without derivatives)">root-finding examples</a>.
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2006-2010, 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="roots_noderiv/implementation.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_finding_examples.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>