mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2026-06-02 22:14:56 -04:00
Squashed 'boost/' content from commit b4feb19f2
git-subtree-dir: boost git-subtree-split: b4feb19f287ee92d87a9624b5d36b7cf46aeadeb
This commit is contained in:
@@ -0,0 +1,778 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>The Effect of a Poor Initial Guess</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.5.1">
|
||||
<link rel="up" href="../roots.html" title="Root finding">
|
||||
<link rel="prev" href="root_finding_examples/elliptic_eg.html" title="A More complex example - Inverting the Elliptic Integrals">
|
||||
<link rel="next" href="bad_roots.html" title="Examples Where Root Finding Goes Wrong">
|
||||
</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="root_finding_examples/elliptic_eg.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots.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="bad_roots.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="math_toolkit.roots.bad_guess"></a><a class="link" href="bad_guess.html" title="The Effect of a Poor Initial Guess">The Effect of a Poor Initial
|
||||
Guess</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
It's instructive to take our "toy" example algorithms, and use
|
||||
deliberately bad initial guesses to see how the various root finding algorithms
|
||||
fair. We'll start with the cubed root, and using the cube root of 500 as
|
||||
the test case:
|
||||
</p>
|
||||
<div class="informaltable"><table class="table">
|
||||
<colgroup>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
</colgroup>
|
||||
<thead><tr>
|
||||
<th>
|
||||
<p>
|
||||
Initial Guess=
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
-500% (≈1.323)
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
-100% (≈3.97)
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
-50% (≈3.96)
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
-20% (≈6.35)
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
-10% (≈7.14)
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
-5% (≈7.54)
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
5% (≈8.33)
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
10% (≈8.73)
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
20% (≈9.52)
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
50% (≈11.91)
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
100% (≈15.87)
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
500 (≈47.6)
|
||||
</p>
|
||||
</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
bracket_and_solve_root
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
12
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
8
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
8
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
10
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
11
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
11
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
11
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
11
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
11
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
11
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
7
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
13
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
newton_iterate
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
12
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
7
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
7
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
5
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
5
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
4
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
4
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
5
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
5
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
6
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
7
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
9
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
halley_iterate
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
7
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
4
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
4
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
4
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
4
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
6
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
schroder_iterate
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
11
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
6
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
6
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
4
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
4
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
5
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
5
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
8
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table></div>
|
||||
<p>
|
||||
As you can see <code class="computeroutput"><span class="identifier">bracket_and_solve_root</span></code>
|
||||
is relatively insensitive to starting location - as long as you don't start
|
||||
many orders of magnitude away from the root it will take roughly the same
|
||||
number of steps to bracket the root and solve it. On the other hand the derivative-based
|
||||
methods are slow to start, but once they have some digits correct they increase
|
||||
precision exceptionally fast: they are therefore quite sensitive to the initial
|
||||
starting location.
|
||||
</p>
|
||||
<p>
|
||||
The next table shows the number of iterations required to find the second
|
||||
radius of an ellipse with first radius 50 and arc-length 500:
|
||||
</p>
|
||||
<div class="informaltable"><table class="table">
|
||||
<colgroup>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
</colgroup>
|
||||
<thead><tr>
|
||||
<th>
|
||||
<p>
|
||||
Initial Guess=
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
-500% (≈20.6)
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
-100% (≈61.81)
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
-50% (≈61.81)
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
-20% (≈98.9)
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
-10% (≈111.3)
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
-5% (≈117.4)
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
5% (≈129.8)
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
10% (≈136)
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
20% (≈148.3)
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
50% (≈185.4)
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
100% (≈247.2)
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
500 (≈741.7)
|
||||
</p>
|
||||
</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
bracket_and_solve_root
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
11
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
5
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
5
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
8
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
8
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
7
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
7
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
8
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
9
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
8
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
6
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
10
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
newton_iterate
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
4
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
4
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
4
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
4
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
4
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
4
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
halley_iterate
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
4
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
2
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
2
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
schroder_iterate
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
4
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
2
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
2
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
3
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table></div>
|
||||
<p>
|
||||
Interestingly this function is much more resistant to a poor initial guess
|
||||
when using derivatives.
|
||||
</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 © 2006-2010, 2012-2014 Nikhar Agrawal,
|
||||
Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
|
||||
Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan Råde, Gautam Sewani,
|
||||
Benjamin Sobotta, 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="root_finding_examples/elliptic_eg.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots.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="bad_roots.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,127 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Examples Where Root Finding Goes Wrong</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.5.1">
|
||||
<link rel="up" href="../roots.html" title="Root finding">
|
||||
<link rel="prev" href="bad_guess.html" title="The Effect of a Poor Initial Guess">
|
||||
<link rel="next" href="brent_minima.html" title="Locating Function Minima using Brent's algorithm">
|
||||
</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_guess.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots.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="brent_minima.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="math_toolkit.roots.bad_roots"></a><a class="link" href="bad_roots.html" title="Examples Where Root Finding Goes Wrong">Examples Where Root Finding
|
||||
Goes Wrong</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
There are many reasons why root root finding can fail, here are just a few
|
||||
of the more common examples:
|
||||
</p>
|
||||
<h4>
|
||||
<a name="math_toolkit.roots.bad_roots.h0"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.bad_roots.local_minima"></a></span><a class="link" href="bad_roots.html#math_toolkit.roots.bad_roots.local_minima">Local
|
||||
Minima</a>
|
||||
</h4>
|
||||
<p>
|
||||
If you start in the wrong place, such as z<sub>0</sub> here:
|
||||
</p>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><object type="image/svg+xml" data="../../../roots/bad_root_1.svg" width="372" height="262"></object></span>
|
||||
</p>
|
||||
<p>
|
||||
Then almost any root-finding algorithm will descend into a local minima rather
|
||||
than find the root.
|
||||
</p>
|
||||
<h4>
|
||||
<a name="math_toolkit.roots.bad_roots.h1"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.bad_roots.flatlining"></a></span><a class="link" href="bad_roots.html#math_toolkit.roots.bad_roots.flatlining">Flatlining</a>
|
||||
</h4>
|
||||
<p>
|
||||
In this example, we're starting from a location (z<sub>0</sub>) where the first derivative
|
||||
is essentially zero:
|
||||
</p>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><object type="image/svg+xml" data="../../../roots/bad_root_2.svg" width="372" height="262"></object></span>
|
||||
</p>
|
||||
<p>
|
||||
In this situation the next iteration will shoot off to infinity (assuming
|
||||
we're using derivatives that is). Our code guards against this by insisting
|
||||
that the root is always bracketed, and then never stepping outside those
|
||||
bounds. In a case like this, no root finding algorithm can do better than
|
||||
bisecting until the root is found.
|
||||
</p>
|
||||
<p>
|
||||
Note that there is no scale on the graph, we have seen examples of this situation
|
||||
occur in practice <span class="emphasis"><em>even when several decimal places of the initial
|
||||
guess z<sub>0</sub> are correct.</em></span>
|
||||
</p>
|
||||
<p>
|
||||
This is really a special case of a more common situation where root finding
|
||||
with derivatives is <span class="emphasis"><em>divergent</em></span>. Consider starting at
|
||||
z<sub>0</sub> in this case:
|
||||
</p>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><object type="image/svg+xml" data="../../../roots/bad_root_4.svg" width="372" height="262"></object></span>
|
||||
</p>
|
||||
<p>
|
||||
An initial Newton step would take you further from the root than you started,
|
||||
as will all subsequent steps.
|
||||
</p>
|
||||
<h4>
|
||||
<a name="math_toolkit.roots.bad_roots.h2"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.bad_roots.micro_stepping_non_convergence"></a></span><a class="link" href="bad_roots.html#math_toolkit.roots.bad_roots.micro_stepping_non_convergence">Micro-stepping
|
||||
/ Non-convergence</a>
|
||||
</h4>
|
||||
<p>
|
||||
Consider starting at z<sub>0</sub> in this situation:
|
||||
</p>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><object type="image/svg+xml" data="../../../roots/bad_root_3.svg" width="372" height="262"></object></span>
|
||||
</p>
|
||||
<p>
|
||||
The first derivative is essentially infinite, and the second close to zero
|
||||
(and so offers no correction if we use it), as a result we take a very small
|
||||
first step. In the worst case situation, the first step is so small - perhaps
|
||||
even so small that subtracting from z<sub>0</sub> has no effect at the current working
|
||||
precision - that our algorithm will assume we are at the root already and
|
||||
terminate. Otherwise we will take lot's of very small steps which never converge
|
||||
on the root: our algorithms will protect against that by reverting to bisection.
|
||||
</p>
|
||||
<p>
|
||||
An example of this situation would be trying to find the root of e<sup>-1/z<sup>2</sup></sup> -
|
||||
this function has a single root at <span class="emphasis"><em>z = 0</em></span>, but for <span class="emphasis"><em>z<sub>0</sub> <
|
||||
0</em></span> neither Newton nor Halley steps will ever converge on the root,
|
||||
and for <span class="emphasis"><em>z<sub>0</sub> > 0</em></span> the steps are actually divergent.
|
||||
</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 © 2006-2010, 2012-2014 Nikhar Agrawal,
|
||||
Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
|
||||
Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan Råde, Gautam Sewani,
|
||||
Benjamin Sobotta, 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_guess.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots.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="brent_minima.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,612 @@
|
||||
<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.5.1">
|
||||
<link rel="up" href="../roots.html" title="Root finding">
|
||||
<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="../roots.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><h3 class="title">
|
||||
<a name="math_toolkit.roots.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>
|
||||
</h3></div></div></div>
|
||||
<h5>
|
||||
<a name="math_toolkit.roots.brent_minima.h0"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.brent_minima.synopsis"></a></span><a class="link" href="brent_minima.html#math_toolkit.roots.brent_minima.synopsis">Synopsis</a>
|
||||
</h5>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">tools</span><span class="special">/</span><span class="identifier">minima</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
</pre>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</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">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></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"><</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">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></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">&</span> <span class="identifier">max_iter</span><span class="special">);</span>
|
||||
</pre>
|
||||
<h5>
|
||||
<a name="math_toolkit.roots.brent_minima.h1"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.brent_minima.description"></a></span><a class="link" href="brent_minima.html#math_toolkit.roots.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)≅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.roots.brent_minima.h2"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.brent_minima.example"></a></span><a class="link" href="brent_minima.html#math_toolkit.roots.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"><</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">></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">&</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"><</span><span class="keyword">double</span><span class="special">>::</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"><</span><span class="keyword">double</span><span class="special">>::</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"><</span><span class="keyword">double</span><span class="special">>::</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"><</span><span class="keyword">double</span><span class="special">,</span> <span class="keyword">double</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">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"><</span><span class="keyword">double</span><span class="special">>::</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"><<</span> <span class="string">"x at minimum = "</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="string">", f("</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="string">") = "</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">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"><</span><span class="keyword">double</span><span class="special">>::</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"><</span><span class="keyword">double</span><span class="special">>::</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"><</span><span class="keyword">class</span> <span class="identifier">T</span> <span class="special">=</span> <span class="keyword">double</span><span class="special">></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"><</span><span class="identifier">T</span><span class="special">>(</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"><</span><span class="identifier">T</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="keyword">else</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">is_close_to</span><span class="special"><</span><span class="identifier">T</span><span class="special">>(</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"><<</span> <span class="string">"x at minimum = "</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="string">", f("</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="string">") = "</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="string">" after "</span> <span class="special"><<</span> <span class="identifier">it</span> <span class="special"><<</span> <span class="string">" iterations. "</span> <span class="special"><<</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"><</span><span class="keyword">int</span><span class="special">>(</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"><<</span> <span class="string">"Showing "</span> <span class="special"><<</span> <span class="identifier">bits</span> <span class="special"><<</span> <span class="string">" bits precision with "</span> <span class="special"><<</span> <span class="identifier">prec</span>
|
||||
<span class="special"><<</span> <span class="string">" decimal digits from tolerance "</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"><</span><span class="keyword">double</span><span class="special">>::</span><span class="identifier">epsilon</span><span class="special">())</span>
|
||||
<span class="special"><<</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"><<</span> <span class="string">"x at minimum = "</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="string">", f("</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="string">") = "</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="string">" after "</span> <span class="special"><<</span> <span class="identifier">it</span> <span class="special"><<</span> <span class="string">" iterations. "</span> <span class="special"><<</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"><-(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">double</span><span class="special">>::</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">>(</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"><<</span> <span class="string">"Showing "</span> <span class="special"><<</span> <span class="identifier">bits</span> <span class="special"><<</span> <span class="string">" bits precision with "</span> <span class="special"><<</span> <span class="identifier">prec</span>
|
||||
<span class="special"><<</span> <span class="string">" decimal digits from tolerance "</span> <span class="special"><<</span> <span class="identifier">sqrt</span><span class="special">(</span><span class="identifier">epsilon_2</span><span class="special">)</span>
|
||||
<span class="special"><<</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"><<</span> <span class="string">"x at minimum = "</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="string">", f("</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="string">") = "</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">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"><<</span> <span class="identifier">it</span> <span class="special"><<</span> <span class="string">" iterations. "</span> <span class="special"><<</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"><-(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">double</span><span class="special">>::</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">>(</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"><<</span> <span class="string">"Showing "</span> <span class="special"><<</span> <span class="identifier">bits</span> <span class="special"><<</span> <span class="string">" bits precision with "</span> <span class="special"><<</span> <span class="identifier">prec</span>
|
||||
<span class="special"><<</span> <span class="string">" decimal digits from tolerance "</span> <span class="special"><<</span> <span class="identifier">sqrt</span><span class="special">(</span><span class="identifier">epsilon_4</span><span class="special">)</span>
|
||||
<span class="special"><<</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"><<</span> <span class="string">"x at minimum = "</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="string">", f("</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="string">") = "</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="string">", after "</span> <span class="special"><<</span> <span class="identifier">it</span> <span class="special"><<</span> <span class="string">" iterations. "</span> <span class="special"><<</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.roots.brent_minima.h3"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.brent_minima.template"></a></span><a class="link" href="brent_minima.html#math_toolkit.roots.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"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></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">&</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"><</span><span class="keyword">long</span> <span class="keyword">double</span><span class="special">>::</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"><</span><span class="keyword">long</span> <span class="keyword">double</span><span class="special">>::</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"><</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">></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"><<</span> <span class="string">"x at minimum = "</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="string">", f("</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="string">") = "</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="string">", after "</span> <span class="special"><<</span> <span class="identifier">it</span> <span class="special"><<</span> <span class="string">" iterations. "</span> <span class="special"><<</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"><</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">></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="keyword">long</span> <span class="keyword">double</span><span class="special">></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"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></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"><</span><span class="identifier">T</span><span class="special">>::</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"><</span><span class="keyword">int</span><span class="special">>(</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"><<</span> <span class="string">"\n\nFor type "</span> <span class="special"><<</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"><<</span> <span class="string">",\n epsilon = "</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">epsilon</span><span class="special">()</span>
|
||||
<span class="comment">// << ", precision of " << bits << " bits"</span>
|
||||
<span class="special"><<</span> <span class="string">",\n the maximum theoretical precision from Brent minimization is "</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"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">epsilon</span><span class="special">())</span>
|
||||
<span class="special"><<</span> <span class="string">"\n Displaying to std::numeric_limits<T>::digits10 "</span> <span class="special"><<</span> <span class="identifier">prec</span> <span class="special"><<</span> <span class="string">" significant decimal digits."</span>
|
||||
<span class="special"><<</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<T>("-4");</span>
|
||||
<span class="comment">//T bracket_max = static_cast<T>("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"><</span><span class="identifier">T</span><span class="special">>(-</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"><</span><span class="identifier">T</span><span class="special">>(</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"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</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">func</span><span class="special">,</span> <span class="identifier">T</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"><<</span> <span class="string">" x at minimum = "</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="string">", f("</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="string">") = "</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="keyword">if</span> <span class="special">(</span><span class="identifier">it</span> <span class="special"><</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"><<</span> <span class="string">",\n met "</span> <span class="special"><<</span> <span class="identifier">bits</span> <span class="special"><<</span> <span class="string">" bits precision"</span> <span class="special"><<</span> <span class="string">", after "</span> <span class="special"><<</span> <span class="identifier">it</span> <span class="special"><<</span> <span class="string">" iterations."</span> <span class="special"><<</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"><<</span> <span class="string">",\n did NOT meet "</span> <span class="special"><<</span> <span class="identifier">bits</span> <span class="special"><<</span> <span class="string">" bits precision"</span> <span class="special"><<</span> <span class="string">" after "</span> <span class="special"><<</span> <span class="identifier">it</span> <span class="special"><<</span> <span class="string">" iterations!"</span> <span class="special"><<</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"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">epsilon</span><span class="special">());</span>
|
||||
<span class="comment">//std::cout << std::boolalpha << "x == 1 (compared to uncertainty " << uncertainty << ") is " << close(static_cast<T>(1), r.first, uncertainty) << std::endl;</span>
|
||||
<span class="comment">//std::cout << std::boolalpha << "f(x) == (0 compared to uncertainty " << uncertainty << ") is " << close(static_cast<T>(0), r.second, uncertainty) << 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">&</span> <span class="identifier">e</span><span class="special">)</span>
|
||||
<span class="special">{</span> <span class="comment">// Always useful to include try & 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 & 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"><<</span>
|
||||
<span class="string">"\n"</span><span class="string">"Message from thrown exception was:\n "</span> <span class="special"><<</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special"><<</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"><</span><span class="keyword">float</span><span class="special">>();</span>
|
||||
<span class="identifier">show_minima</span><span class="special"><</span><span class="keyword">double</span><span class="special">>();</span>
|
||||
<span class="identifier">show_minima</span><span class="special"><</span><span class="keyword">long</span> <span class="keyword">double</span><span class="special">>();</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"><</span><span class="identifier">float128</span><span class="special">>();</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.roots.brent_minima.h4"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.brent_minima.multiprecision"></a></span><a class="link" href="brent_minima.html#math_toolkit.roots.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"><</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">></span> <span class="comment">// For decimal boost::multiprecision::cpp_dec_float_50.</span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</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">></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"><</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="number">50</span><span class="special">>,</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">></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"><</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="number">50</span><span class="special">>,</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">></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"><</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="number">50</span><span class="special">>,</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">></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"><</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="number">50</span><span class="special">>,</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">></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"><</span><span class="identifier">cpp_bin_float_50</span><span class="special">>::</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"><</span> <span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">cpp_bin_float_50</span><span class="special">>(</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"><<</span> <span class="identifier">fpv</span> <span class="special"><<</span> <span class="char">' '</span> <span class="special"><<</span> <span class="identifier">absv</span> <span class="special"><<</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"><</span><span class="identifier">cpp_bin_float_50</span><span class="special">>::</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"><</span><span class="identifier">cpp_bin_float_50</span><span class="special">>(</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"><</span><span class="identifier">cpp_bin_float_50</span><span class="special">>(</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"><<</span> <span class="identifier">bracket_min</span> <span class="special"><<</span> <span class="string">" "</span> <span class="special"><<</span> <span class="identifier">bracket_max</span> <span class="special"><<</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"><</span><span class="identifier">cpp_bin_float_50</span><span class="special">,</span> <span class="identifier">cpp_bin_float_50</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">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"><<</span> <span class="string">"x at minimum = "</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="string">", f("</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="string">") = "</span> <span class="special"><<</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"><<</span> <span class="string">", after "</span> <span class="special"><<</span> <span class="identifier">it</span> <span class="special"><<</span> <span class="string">" iterations. "</span> <span class="special"><<</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"><</span><span class="identifier">cpp_bin_float_50</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">sqrt</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">cpp_bin_float_50</span><span class="special">>::</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"><</span><span class="identifier">cpp_bin_float_50_et_on</span><span class="special">>();</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"><</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"><</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">>,</span> <span class="number">1</span><span class="special">>,</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"><</span><span class="identifier">T</span><span class="special">>::</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"><</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"><</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">>,</span> <span class="number">1</span><span class="special">>,</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"><</span><span class="identifier">T</span><span class="special">>::</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"><</span><span class="identifier">T</span><span class="special">>::</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.roots.brent_minima.h5"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.brent_minima.implementation"></a></span><a class="link" href="brent_minima.html#math_toolkit.roots.brent_minima.implementation">Implementation</a>
|
||||
</h5>
|
||||
<p>
|
||||
This is a reasonably faithful implementation of Brent's algorithm.
|
||||
</p>
|
||||
<h5>
|
||||
<a name="math_toolkit.roots.brent_minima.h6"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.brent_minima.references"></a></span><a class="link" href="brent_minima.html#math_toolkit.roots.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 © 2006-2010, 2012-2014 Nikhar Agrawal,
|
||||
Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
|
||||
Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan Råde, Gautam Sewani,
|
||||
Benjamin Sobotta, 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="../roots.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>
|
||||
@@ -0,0 +1,312 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Polynomials</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.5.1">
|
||||
<link rel="up" href="../roots.html" title="Root finding">
|
||||
<link rel="prev" href="root_comparison/elliptic_comparison.html" title="Comparison of Elliptic Integral Root Finding Algoritghms">
|
||||
<link rel="next" href="rational.html" title="Polynomial and Rational Function Evaluation">
|
||||
</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="root_comparison/elliptic_comparison.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots.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="rational.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="math_toolkit.roots.polynomials"></a><a class="link" href="polynomials.html" title="Polynomials">Polynomials</a>
|
||||
</h3></div></div></div>
|
||||
<h5>
|
||||
<a name="math_toolkit.roots.polynomials.h0"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.polynomials.synopsis"></a></span><a class="link" href="polynomials.html#math_toolkit.roots.polynomials.synopsis">Synopsis</a>
|
||||
</h5>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">tools</span><span class="special">/</span><span class="identifier">polynomial</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></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="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">class</span> <span class="identifier">polynomial</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">public</span><span class="special">:</span>
|
||||
<span class="comment">// typedefs:</span>
|
||||
<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value_type</span> <span class="identifier">value_type</span><span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">size_type</span> <span class="identifier">size_type</span><span class="special">;</span>
|
||||
|
||||
<span class="comment">// construct:</span>
|
||||
<span class="identifier">polynomial</span><span class="special">(){}</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">U</span><span class="special">*</span> <span class="identifier">data</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="identifier">order</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">I</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special">(</span><span class="identifier">I</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">I</span> <span class="identifier">last</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
|
||||
<span class="keyword">explicit</span> <span class="identifier">polynomial</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">U</span><span class="special">&</span> <span class="identifier">point</span><span class="special">);</span>
|
||||
<span class="identifier">polynomial</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">initializer_list</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">l</span><span class="special">);</span> <span class="comment">// C++11</span>
|
||||
|
||||
<span class="comment">// access:</span>
|
||||
<span class="identifier">size_type</span> <span class="identifier">size</span><span class="special">()</span><span class="keyword">const</span><span class="special">;</span>
|
||||
<span class="identifier">size_type</span> <span class="identifier">degree</span><span class="special">()</span><span class="keyword">const</span><span class="special">;</span>
|
||||
<span class="identifier">value_type</span><span class="special">&</span> <span class="keyword">operator</span><span class="special">[](</span><span class="identifier">size_type</span> <span class="identifier">i</span><span class="special">);</span>
|
||||
<span class="keyword">const</span> <span class="identifier">value_type</span><span class="special">&</span> <span class="keyword">operator</span><span class="special">[](</span><span class="identifier">size_type</span> <span class="identifier">i</span><span class="special">)</span><span class="keyword">const</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">data</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">data</span><span class="special">();</span>
|
||||
<span class="keyword">explicit</span> <span class="keyword">operator</span> <span class="keyword">bool</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
|
||||
|
||||
<span class="comment">// modify:</span>
|
||||
<span class="keyword">void</span> <span class="identifier">set_zero</span><span class="special">();</span>
|
||||
|
||||
<span class="comment">// operators:</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">+=(</span><span class="keyword">const</span> <span class="identifier">U</span><span class="special">&</span> <span class="identifier">value</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">-=(</span><span class="keyword">const</span> <span class="identifier">U</span><span class="special">&</span> <span class="identifier">value</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">*=(</span><span class="keyword">const</span> <span class="identifier">U</span><span class="special">&</span> <span class="identifier">value</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">/=(</span><span class="keyword">const</span> <span class="identifier">U</span><span class="special">&</span> <span class="identifier">value</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">%=(</span><span class="keyword">const</span> <span class="identifier">U</span><span class="special">&</span> <span class="identifier">value</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">+=(</span><span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">U</span><span class="special">>&</span> <span class="identifier">value</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">-=(</span><span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">U</span><span class="special">>&</span> <span class="identifier">value</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">*=(</span><span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">U</span><span class="special">>&</span> <span class="identifier">value</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">/=(</span><span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">U</span><span class="special">>&</span> <span class="identifier">value</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">%=(</span><span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">U</span><span class="special">>&</span> <span class="identifier">value</span><span class="special">);</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">operator</span> <span class="special">+</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">b</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">operator</span> <span class="special">-</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">b</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">operator</span> <span class="special">*</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">b</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">operator</span> <span class="special">/</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">b</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">operator</span> <span class="special">%</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">b</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">operator</span> <span class="special">+</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">U</span><span class="special">&</span> <span class="identifier">b</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">operator</span> <span class="special">-</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">U</span><span class="special">&</span> <span class="identifier">b</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">operator</span> <span class="special">*</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">U</span><span class="special">&</span> <span class="identifier">b</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">operator</span> <span class="special">/</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">U</span><span class="special">&</span> <span class="identifier">b</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">operator</span> <span class="special">%</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">U</span><span class="special">&</span> <span class="identifier">b</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">operator</span> <span class="special">+</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">U</span><span class="special">&</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">b</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">operator</span> <span class="special">-</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">U</span><span class="special">&</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">b</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">operator</span> <span class="special">*</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">U</span><span class="special">&</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">b</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">operator</span> <span class="special">-</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">a</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">operator</span> <span class="special">>>=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">U</span><span class="special">&</span> <span class="identifier">a</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">operator</span> <span class="special">>></span> <span class="special">(</span><span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">U</span><span class="special">&</span> <span class="identifier">b</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">operator</span> <span class="special"><<=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">U</span><span class="special">&</span> <span class="identifier">a</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">operator</span> <span class="special"><<</span> <span class="special">(</span><span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">U</span><span class="special">&</span> <span class="identifier">b</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">b</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">!=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">b</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">pow</span><span class="special">(</span><span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">base</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">exp</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special"><</span><span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traits</span><span class="special">>&</span> <span class="keyword">operator</span> <span class="special"><<</span>
|
||||
<span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special"><</span><span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traits</span><span class="special">>&</span> <span class="identifier">os</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">poly</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">>,</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">></span>
|
||||
<span class="identifier">quotient_remainder</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">b</span><span class="special">);</span>
|
||||
|
||||
<span class="special">}</span> <span class="comment">// namespace tools</span>
|
||||
<span class="special">}}</span> <span class="comment">// namespace boost { namespace math</span>
|
||||
</pre>
|
||||
<h5>
|
||||
<a name="math_toolkit.roots.polynomials.h1"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.polynomials.description"></a></span><a class="link" href="polynomials.html#math_toolkit.roots.polynomials.description">Description</a>
|
||||
</h5>
|
||||
<p>
|
||||
This is a somewhat trivial class for polynomial manipulation.
|
||||
</p>
|
||||
<p>
|
||||
See
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<a href="https://en.wikipedia.org/wiki/Polynomial" target="_top">Polynomial</a>
|
||||
and
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Donald E. Knuth, The Art of Computer Programming: Volume 2, Third edition,
|
||||
(1998) Chapter 4.6.1, Algorithm D: Division of polynomials over a field.
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
Implementation is currently of the "naive" variety, with 𝑶(N<sup>2</sup>) multiplication,
|
||||
for example. This class should not be used in high-performance computing
|
||||
environments: it is intended for the simple manipulation of small polynomials,
|
||||
typically generated for special function approximation.
|
||||
</p>
|
||||
<p>
|
||||
It does has division for polynomials over a <a href="https://en.wikipedia.org/wiki/Field_%28mathematics%29" target="_top">field</a>
|
||||
(here floating point, complex, etc) and over a unique factorization domain
|
||||
(integers). Division of polynomials over a field is compatible with <a href="https://en.wikipedia.org/wiki/Euclidean_algorithm" target="_top">Euclidean GCD</a>.
|
||||
</p>
|
||||
<p>
|
||||
Advanced manipulations: the FFT, factorisation etc are not currently provided.
|
||||
Submissions for these are of course welcome :-)
|
||||
</p>
|
||||
<h5>
|
||||
<a name="math_toolkit.roots.polynomials.h2"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.polynomials.polynomial_examples"></a></span><a class="link" href="polynomials.html#math_toolkit.roots.polynomials.polynomial_examples">Polynomial
|
||||
Arithmetic Examples</a>
|
||||
</h5>
|
||||
<p>
|
||||
First include the essential polynomial header (and others) to make the example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">tools</span><span class="special">/</span><span class="identifier">polynomial</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
</pre>
|
||||
<p>
|
||||
and some using statements are convenient:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">using</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">;</span>
|
||||
<span class="keyword">using</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">exception</span><span class="special">;</span>
|
||||
<span class="keyword">using</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">;</span>
|
||||
<span class="keyword">using</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">abs</span><span class="special">;</span>
|
||||
<span class="keyword">using</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">;</span>
|
||||
|
||||
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">;</span>
|
||||
<span class="keyword">using</span> <span class="keyword">namespace</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="comment">// for polynomial</span>
|
||||
<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">lexical_cast</span><span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
Store the coefficients in a convenient way to access them, then create some
|
||||
polynomials using construction from an iterator range, and finally output
|
||||
in a 'pretty' formula format.
|
||||
</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>
|
||||
Although we might conventionally write a polynomial from left to right
|
||||
in descending order of degree, Boost.Math stores in <span class="bold"><strong>ascending
|
||||
order of degree</strong></span>.
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
<pre class="programlisting"><span class="identifier">Read</span><span class="special">/</span><span class="identifier">write</span> <span class="keyword">for</span> <span class="identifier">humans</span><span class="special">:</span> <span class="number">3</span><span class="identifier">x</span><span class="special">^</span><span class="number">3</span> <span class="special">-</span> <span class="number">4</span><span class="identifier">x</span><span class="special">^</span><span class="number">2</span> <span class="special">-</span> <span class="number">6</span><span class="identifier">x</span> <span class="special">+</span> <span class="number">10</span>
|
||||
<span class="identifier">Boost</span> <span class="identifier">polynomial</span> <span class="identifier">storage</span><span class="special">:</span> <span class="special">[</span> <span class="number">10</span><span class="special">,</span> <span class="special">-</span><span class="number">6</span><span class="special">,</span> <span class="special">-</span><span class="number">4</span><span class="special">,</span> <span class="number">3</span> <span class="special">]</span>
|
||||
</pre>
|
||||
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</span><span class="keyword">double</span><span class="special">,</span> <span class="number">4</span><span class="special">></span> <span class="keyword">const</span> <span class="identifier">d3a</span> <span class="special">=</span> <span class="special">{{</span><span class="number">10</span><span class="special">,</span> <span class="special">-</span><span class="number">6</span><span class="special">,</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">polynomial</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span> <span class="keyword">const</span> <span class="identifier">a</span><span class="special">(</span><span class="identifier">d3a</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">d3a</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span>
|
||||
|
||||
<span class="comment">// With C++11 and later, you can also use initializer_list construction.</span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span> <span class="keyword">const</span> <span class="identifier">b</span><span class="special">{{-</span><span class="number">2.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">}};</span>
|
||||
|
||||
<span class="comment">// formula_format() converts from Boost storage to human notation.</span>
|
||||
<span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"a = "</span> <span class="special"><<</span> <span class="identifier">formula_format</span><span class="special">(</span><span class="identifier">a</span><span class="special">)</span>
|
||||
<span class="special"><<</span> <span class="string">"\nb = "</span> <span class="special"><<</span> <span class="identifier">formula_format</span><span class="special">(</span><span class="identifier">b</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"\n\n"</span><span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
for output:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">a</span> <span class="special">=</span> <span class="number">3</span><span class="identifier">x</span><span class="special">^</span><span class="number">3</span> <span class="special">-</span> <span class="number">4</span><span class="identifier">x</span><span class="special">^</span><span class="number">2</span> <span class="special">-</span> <span class="number">6</span><span class="identifier">x</span> <span class="special">+</span> <span class="number">10</span>
|
||||
<span class="identifier">b</span> <span class="special">=</span> <span class="identifier">x</span> <span class="special">-</span> <span class="number">2</span>
|
||||
</pre>
|
||||
<pre class="programlisting"><span class="comment">// Now we can do arithmetic with the usual infix operators: + - * / and %.</span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span> <span class="identifier">s</span> <span class="special">=</span> <span class="identifier">a</span> <span class="special">+</span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"a + b = "</span> <span class="special"><<</span> <span class="identifier">formula_format</span><span class="special">(</span><span class="identifier">s</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"\n"</span><span class="special">;</span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span> <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">a</span> <span class="special">-</span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"a - b = "</span> <span class="special"><<</span> <span class="identifier">formula_format</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"\n"</span><span class="special">;</span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span> <span class="identifier">p</span> <span class="special">=</span> <span class="identifier">a</span> <span class="special">*</span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"a * b = "</span> <span class="special"><<</span> <span class="identifier">formula_format</span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"\n"</span><span class="special">;</span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span> <span class="identifier">q</span> <span class="special">=</span> <span class="identifier">a</span> <span class="special">/</span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"a / b = "</span> <span class="special"><<</span> <span class="identifier">formula_format</span><span class="special">(</span><span class="identifier">q</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"\n"</span><span class="special">;</span>
|
||||
<span class="identifier">polynomial</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">a</span> <span class="special">%</span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"a % b = "</span> <span class="special"><<</span> <span class="identifier">formula_format</span><span class="special">(</span><span class="identifier">r</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"\n"</span><span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
for output
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">a</span> <span class="special">+</span> <span class="identifier">b</span> <span class="special">=</span> <span class="number">3</span><span class="identifier">x</span><span class="special">^</span><span class="number">3</span> <span class="special">-</span> <span class="number">4</span><span class="identifier">x</span><span class="special">^</span><span class="number">2</span> <span class="special">-</span> <span class="number">5</span><span class="identifier">x</span> <span class="special">+</span> <span class="number">8</span>
|
||||
<span class="identifier">a</span> <span class="special">-</span> <span class="identifier">b</span> <span class="special">=</span> <span class="number">3</span><span class="identifier">x</span><span class="special">^</span><span class="number">3</span> <span class="special">-</span> <span class="number">4</span><span class="identifier">x</span><span class="special">^</span><span class="number">2</span> <span class="special">-</span> <span class="number">7</span><span class="identifier">x</span> <span class="special">+</span> <span class="number">12</span>
|
||||
<span class="identifier">a</span> <span class="special">*</span> <span class="identifier">b</span> <span class="special">=</span> <span class="number">3</span><span class="identifier">x</span><span class="special">^</span><span class="number">4</span> <span class="special">-</span> <span class="number">10</span><span class="identifier">x</span><span class="special">^</span><span class="number">3</span> <span class="special">+</span> <span class="number">2</span><span class="identifier">x</span><span class="special">^</span><span class="number">2</span> <span class="special">+</span> <span class="number">22</span><span class="identifier">x</span> <span class="special">-</span> <span class="number">20</span>
|
||||
<span class="identifier">a</span> <span class="special">/</span> <span class="identifier">b</span> <span class="special">=</span> <span class="number">3</span><span class="identifier">x</span><span class="special">^</span><span class="number">2</span> <span class="special">+</span> <span class="number">2</span><span class="identifier">x</span> <span class="special">-</span> <span class="number">2</span>
|
||||
<span class="identifier">a</span> <span class="special">%</span> <span class="identifier">b</span> <span class="special">=</span> <span class="number">6</span>
|
||||
</pre>
|
||||
<h6>
|
||||
<a name="math_toolkit.roots.polynomials.h3"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.polynomials.division_quotient_and_remainder"></a></span><a class="link" href="polynomials.html#math_toolkit.roots.polynomials.division_quotient_and_remainder">Division,
|
||||
Quotient and Remainder</a>
|
||||
</h6>
|
||||
<p>
|
||||
Division is a special case where you can calculate two for the price of one.
|
||||
</p>
|
||||
<p>
|
||||
Actually, quotient and remainder are always calculated together due to the
|
||||
nature of the algorithm: the infix operators return one result and throw
|
||||
the other away.
|
||||
</p>
|
||||
<p>
|
||||
If you are doing a lot of division and want both the quotient and remainder,
|
||||
then you don't want to do twice the work necessary.
|
||||
</p>
|
||||
<p>
|
||||
In that case you can call the underlying function, <code class="literal">quotient_remainder</code>,
|
||||
to get both results together as a pair.
|
||||
</p>
|
||||
<pre class="programlisting"> <span class="identifier">pair</span><span class="special"><</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="keyword">double</span><span class="special">>,</span> <span class="identifier">polynomial</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span> <span class="special">></span> <span class="identifier">result</span><span class="special">;</span>
|
||||
<span class="identifier">result</span> <span class="special">=</span> <span class="identifier">quotient_remainder</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">);</span>
|
||||
<span class="comment">// Reassure ourselves that the result is the same.</span>
|
||||
<span class="identifier">BOOST_ASSERT</span><span class="special">(</span><span class="identifier">result</span><span class="special">.</span><span class="identifier">first</span> <span class="special">==</span> <span class="identifier">q</span><span class="special">);</span>
|
||||
<span class="identifier">BOOST_ASSERT</span><span class="special">(</span><span class="identifier">result</span><span class="special">.</span><span class="identifier">second</span> <span class="special">==</span> <span class="identifier">r</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
The source code is at <a href="../../../../example/polynomial_arithmetic.cpp" target="_top">polynomial_arithmetic.cpp</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 © 2006-2010, 2012-2014 Nikhar Agrawal,
|
||||
Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
|
||||
Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan Råde, Gautam Sewani,
|
||||
Benjamin Sobotta, 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="root_comparison/elliptic_comparison.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots.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="rational.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,232 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Polynomial and Rational Function Evaluation</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.5.1">
|
||||
<link rel="up" href="../roots.html" title="Root finding">
|
||||
<link rel="prev" href="polynomials.html" title="Polynomials">
|
||||
<link rel="next" href="../../internals.html" title="Chapter 13. Internal Details: Series, Rationals and Continued Fractions, Testing, and Development Tools">
|
||||
</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="polynomials.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots.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="../../internals.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="math_toolkit.roots.rational"></a><a class="link" href="rational.html" title="Polynomial and Rational Function Evaluation">Polynomial and Rational
|
||||
Function Evaluation</a>
|
||||
</h3></div></div></div>
|
||||
<h5>
|
||||
<a name="math_toolkit.roots.rational.h0"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.rational.synopsis"></a></span><a class="link" href="rational.html#math_toolkit.roots.rational.synopsis">Synopsis</a>
|
||||
</h5>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">tools</span><span class="special">/</span><span class="identifier">rational</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
</pre>
|
||||
<pre class="programlisting"><span class="comment">// Polynomials:</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">N</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">></span>
|
||||
<span class="identifier">V</span> <span class="identifier">evaluate_polynomial</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">(&</span><span class="identifier">poly</span><span class="special">)[</span><span class="identifier">N</span><span class="special">],</span> <span class="keyword">const</span> <span class="identifier">V</span><span class="special">&</span> <span class="identifier">val</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">N</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">></span>
|
||||
<span class="identifier">V</span> <span class="identifier">evaluate_polynomial</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">N</span><span class="special">>&</span> <span class="identifier">poly</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">V</span><span class="special">&</span> <span class="identifier">val</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
|
||||
<span class="identifier">U</span> <span class="identifier">evaluate_polynomial</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">*</span> <span class="identifier">poly</span><span class="special">,</span> <span class="identifier">U</span> <span class="identifier">z</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">count</span><span class="special">);</span>
|
||||
|
||||
<span class="comment">// Even polynomials:</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">N</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">></span>
|
||||
<span class="identifier">V</span> <span class="identifier">evaluate_even_polynomial</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">(&</span><span class="identifier">poly</span><span class="special">)[</span><span class="identifier">N</span><span class="special">],</span> <span class="keyword">const</span> <span class="identifier">V</span><span class="special">&</span> <span class="identifier">z</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">N</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">></span>
|
||||
<span class="identifier">V</span> <span class="identifier">evaluate_even_polynomial</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">N</span><span class="special">>&</span> <span class="identifier">poly</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">V</span><span class="special">&</span> <span class="identifier">z</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
|
||||
<span class="identifier">U</span> <span class="identifier">evaluate_even_polynomial</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">*</span> <span class="identifier">poly</span><span class="special">,</span> <span class="identifier">U</span> <span class="identifier">z</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">count</span><span class="special">);</span>
|
||||
|
||||
<span class="comment">// Odd polynomials</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">N</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">></span>
|
||||
<span class="identifier">V</span> <span class="identifier">evaluate_odd_polynomial</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">(&</span><span class="identifier">a</span><span class="special">)[</span><span class="identifier">N</span><span class="special">],</span> <span class="keyword">const</span> <span class="identifier">V</span><span class="special">&</span> <span class="identifier">z</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">N</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">></span>
|
||||
<span class="identifier">V</span> <span class="identifier">evaluate_odd_polynomial</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">N</span><span class="special">>&</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">V</span><span class="special">&</span> <span class="identifier">z</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
|
||||
<span class="identifier">U</span> <span class="identifier">evaluate_odd_polynomial</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">*</span> <span class="identifier">poly</span><span class="special">,</span> <span class="identifier">U</span> <span class="identifier">z</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">count</span><span class="special">);</span>
|
||||
|
||||
<span class="comment">// Rational Functions:</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">N</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">></span>
|
||||
<span class="identifier">V</span> <span class="identifier">evaluate_rational</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">(&</span><span class="identifier">a</span><span class="special">)[</span><span class="identifier">N</span><span class="special">],</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">(&</span><span class="identifier">b</span><span class="special">)[</span><span class="identifier">N</span><span class="special">],</span> <span class="keyword">const</span> <span class="identifier">V</span><span class="special">&</span> <span class="identifier">z</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">N</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">></span>
|
||||
<span class="identifier">V</span> <span class="identifier">evaluate_rational</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">N</span><span class="special">>&</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">N</span><span class="special">>&</span> <span class="identifier">b</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">V</span><span class="special">&</span> <span class="identifier">z</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">></span>
|
||||
<span class="identifier">V</span> <span class="identifier">evaluate_rational</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">*</span> <span class="identifier">num</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">U</span><span class="special">*</span> <span class="identifier">denom</span><span class="special">,</span> <span class="identifier">V</span> <span class="identifier">z</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="identifier">count</span><span class="special">);</span>
|
||||
</pre>
|
||||
<h5>
|
||||
<a name="math_toolkit.roots.rational.h1"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.rational.description"></a></span><a class="link" href="rational.html#math_toolkit.roots.rational.description">Description</a>
|
||||
</h5>
|
||||
<p>
|
||||
Each of the functions come in three variants: a pair of overloaded functions
|
||||
where the order of the polynomial or rational function is evaluated at compile
|
||||
time, and an overload that accepts a runtime variable for the size of the
|
||||
coefficient array. Generally speaking, compile time evaluation of the array
|
||||
size results in better type safety, is less prone to programmer errors, and
|
||||
may result in better optimised code. The polynomial evaluation functions
|
||||
in particular, are specialised for various array sizes, allowing for loop
|
||||
unrolling, and one hopes, optimal inline expansion.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">N</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">></span>
|
||||
<span class="identifier">V</span> <span class="identifier">evaluate_polynomial</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">(&</span><span class="identifier">poly</span><span class="special">)[</span><span class="identifier">N</span><span class="special">],</span> <span class="keyword">const</span> <span class="identifier">V</span><span class="special">&</span> <span class="identifier">val</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">N</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">></span>
|
||||
<span class="identifier">V</span> <span class="identifier">evaluate_polynomial</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">N</span><span class="special">>&</span> <span class="identifier">poly</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">V</span><span class="special">&</span> <span class="identifier">val</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
|
||||
<span class="identifier">U</span> <span class="identifier">evaluate_polynomial</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">*</span> <span class="identifier">poly</span><span class="special">,</span> <span class="identifier">U</span> <span class="identifier">z</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">count</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
Evaluates the <a href="http://en.wikipedia.org/wiki/Polynomial" target="_top">polynomial</a>
|
||||
described by the coefficients stored in <span class="emphasis"><em>poly</em></span>.
|
||||
</p>
|
||||
<p>
|
||||
If the size of the array is specified at runtime, then the polynomial most
|
||||
have order <span class="emphasis"><em>count-1</em></span> with <span class="emphasis"><em>count</em></span> coefficients.
|
||||
Otherwise it has order <span class="emphasis"><em>N-1</em></span> with <span class="emphasis"><em>N</em></span>
|
||||
coefficients.
|
||||
</p>
|
||||
<p>
|
||||
Coefficients should be stored such that the coefficients for the x<sup>i</sup> terms
|
||||
are in poly[i].
|
||||
</p>
|
||||
<p>
|
||||
The types of the coefficients and of variable <span class="emphasis"><em>z</em></span> may
|
||||
differ as long as <span class="emphasis"><em>*poly</em></span> is convertible to type <span class="emphasis"><em>U</em></span>.
|
||||
This allows, for example, for the coefficient table to be a table of integers
|
||||
if this is appropriate.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">N</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">></span>
|
||||
<span class="identifier">V</span> <span class="identifier">evaluate_even_polynomial</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">(&</span><span class="identifier">poly</span><span class="special">)[</span><span class="identifier">N</span><span class="special">],</span> <span class="keyword">const</span> <span class="identifier">V</span><span class="special">&</span> <span class="identifier">z</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">N</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">></span>
|
||||
<span class="identifier">V</span> <span class="identifier">evaluate_even_polynomial</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">N</span><span class="special">>&</span> <span class="identifier">poly</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">V</span><span class="special">&</span> <span class="identifier">z</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
|
||||
<span class="identifier">U</span> <span class="identifier">evaluate_even_polynomial</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">*</span> <span class="identifier">poly</span><span class="special">,</span> <span class="identifier">U</span> <span class="identifier">z</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">count</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
As above, but evaluates an even polynomial: one where all the powers of
|
||||
<span class="emphasis"><em>z</em></span> are even numbers. Equivalent to calling <code class="computeroutput"><span class="identifier">evaluate_polynomial</span><span class="special">(</span><span class="identifier">poly</span><span class="special">,</span> <span class="identifier">z</span><span class="special">*</span><span class="identifier">z</span><span class="special">,</span> <span class="identifier">count</span><span class="special">)</span></code>.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">N</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">></span>
|
||||
<span class="identifier">V</span> <span class="identifier">evaluate_odd_polynomial</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">(&</span><span class="identifier">a</span><span class="special">)[</span><span class="identifier">N</span><span class="special">],</span> <span class="keyword">const</span> <span class="identifier">V</span><span class="special">&</span> <span class="identifier">z</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">N</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">></span>
|
||||
<span class="identifier">V</span> <span class="identifier">evaluate_odd_polynomial</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">N</span><span class="special">>&</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">V</span><span class="special">&</span> <span class="identifier">z</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
|
||||
<span class="identifier">U</span> <span class="identifier">evaluate_odd_polynomial</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">*</span> <span class="identifier">poly</span><span class="special">,</span> <span class="identifier">U</span> <span class="identifier">z</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">count</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
As above but evaluates a polynomial where all the powers are odd numbers.
|
||||
Equivalent to <code class="computeroutput"><span class="identifier">evaluate_polynomial</span><span class="special">(</span><span class="identifier">poly</span><span class="special">+</span><span class="number">1</span><span class="special">,</span> <span class="identifier">z</span><span class="special">*</span><span class="identifier">z</span><span class="special">,</span>
|
||||
<span class="identifier">count</span><span class="special">-</span><span class="number">1</span><span class="special">)</span> <span class="special">*</span>
|
||||
<span class="identifier">z</span> <span class="special">+</span> <span class="identifier">poly</span><span class="special">[</span><span class="number">0</span><span class="special">]</span></code>.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">N</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">></span>
|
||||
<span class="identifier">V</span> <span class="identifier">evaluate_rational</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">(&</span><span class="identifier">num</span><span class="special">)[</span><span class="identifier">N</span><span class="special">],</span> <span class="keyword">const</span> <span class="identifier">U</span><span class="special">(&</span><span class="identifier">denom</span><span class="special">)[</span><span class="identifier">N</span><span class="special">],</span> <span class="keyword">const</span> <span class="identifier">V</span><span class="special">&</span> <span class="identifier">z</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">N</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">></span>
|
||||
<span class="identifier">V</span> <span class="identifier">evaluate_rational</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">N</span><span class="special">>&</span> <span class="identifier">num</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</span><span class="identifier">U</span><span class="special">,</span><span class="identifier">N</span><span class="special">>&</span> <span class="identifier">denom</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">V</span><span class="special">&</span> <span class="identifier">z</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">></span>
|
||||
<span class="identifier">V</span> <span class="identifier">evaluate_rational</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">*</span> <span class="identifier">num</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">U</span><span class="special">*</span> <span class="identifier">denom</span><span class="special">,</span> <span class="identifier">V</span> <span class="identifier">z</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="identifier">count</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
Evaluates the rational function (the ratio of two polynomials) described
|
||||
by the coefficients stored in <span class="emphasis"><em>num</em></span> and <span class="emphasis"><em>demom</em></span>.
|
||||
</p>
|
||||
<p>
|
||||
If the size of the array is specified at runtime then both polynomials most
|
||||
have order <span class="emphasis"><em>count-1</em></span> with <span class="emphasis"><em>count</em></span> coefficients.
|
||||
Otherwise both polynomials have order <span class="emphasis"><em>N-1</em></span> with <span class="emphasis"><em>N</em></span>
|
||||
coefficients.
|
||||
</p>
|
||||
<p>
|
||||
Array <span class="emphasis"><em>num</em></span> describes the numerator, and <span class="emphasis"><em>demon</em></span>
|
||||
the denominator.
|
||||
</p>
|
||||
<p>
|
||||
Coefficients should be stored such that the coefficients for the x<sup>i </sup> terms
|
||||
are in num[i] and denom[i].
|
||||
</p>
|
||||
<p>
|
||||
The types of the coefficients and of variable <span class="emphasis"><em>v</em></span> may
|
||||
differ as long as <span class="emphasis"><em>*num</em></span> and <span class="emphasis"><em>*denom</em></span>
|
||||
are convertible to type <span class="emphasis"><em>V</em></span>. This allows, for example,
|
||||
for one or both of the coefficient tables to be a table of integers if this
|
||||
is appropriate.
|
||||
</p>
|
||||
<p>
|
||||
These functions are designed to safely evaluate the result, even when the
|
||||
value <span class="emphasis"><em>z</em></span> is very large. As such they do not take advantage
|
||||
of compile time array sizes to make any optimisations. These functions are
|
||||
best reserved for situations where <span class="emphasis"><em>z</em></span> may be large: if
|
||||
you can be sure that numerical overflow will not occur then polynomial evaluation
|
||||
with compile-time array sizes may offer slightly better performance.
|
||||
</p>
|
||||
<h5>
|
||||
<a name="math_toolkit.roots.rational.h2"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.rational.implementation"></a></span><a class="link" href="rational.html#math_toolkit.roots.rational.implementation">Implementation</a>
|
||||
</h5>
|
||||
<p>
|
||||
Polynomials are evaluated by <a href="http://en.wikipedia.org/wiki/Horner_algorithm" target="_top">Horners
|
||||
method</a>. If the array size is known at compile time then the functions
|
||||
dispatch to size-specific implementations that unroll the evaluation loop.
|
||||
</p>
|
||||
<p>
|
||||
Rational evaluation is by <a href="http://en.wikipedia.org/wiki/Horner_algorithm" target="_top">Horners
|
||||
method</a>: with the two polynomials being evaluated in parallel to make
|
||||
the most of the processors floating-point pipeline. If <span class="emphasis"><em>v</em></span>
|
||||
is greater than one, then the polynomials are evaluated in reverse order
|
||||
as polynomials in <span class="emphasis"><em>1/v</em></span>: this avoids unnecessary numerical
|
||||
overflow when the coefficients are large.
|
||||
</p>
|
||||
<p>
|
||||
Both the polynomial and rational function evaluation algorithms can be tuned
|
||||
using various configuration macros to provide optimal performance for a particular
|
||||
combination of compiler and platform. This includes support for second-order
|
||||
Horner's methods. The various options are <a class="link" href="../tuning.html" title="Performance Tuning Macros">documented
|
||||
here</a>. However, the performance benefits to be gained from these are
|
||||
marginal on most current hardware, consequently it's best to run the <a class="link" href="../perf_test_app.html" title="The Performance Test Applications">performance test application</a>
|
||||
before changing the default settings.
|
||||
</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 © 2006-2010, 2012-2014 Nikhar Agrawal,
|
||||
Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
|
||||
Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan Råde, Gautam Sewani,
|
||||
Benjamin Sobotta, 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="polynomials.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots.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="../../internals.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,55 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Comparison of Root Finding Algorithms</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.5.1">
|
||||
<link rel="up" href="../roots.html" title="Root finding">
|
||||
<link rel="prev" href="brent_minima.html" title="Locating Function Minima using Brent's algorithm">
|
||||
<link rel="next" href="root_comparison/cbrt_comparison.html" title="Comparison of Cube 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="brent_minima.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots.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/cbrt_comparison.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="math_toolkit.roots.root_comparison"></a><a class="link" href="root_comparison.html" title="Comparison of Root Finding Algorithms">Comparison of Root
|
||||
Finding Algorithms</a>
|
||||
</h3></div></div></div>
|
||||
<div class="toc"><dl class="toc">
|
||||
<dt><span class="section"><a href="root_comparison/cbrt_comparison.html">Comparison
|
||||
of Cube Root Finding Algorithms</a></span></dt>
|
||||
<dt><span class="section"><a href="root_comparison/root_n_comparison.html">Comparison
|
||||
of Nth-root Finding Algorithms</a></span></dt>
|
||||
<dt><span class="section"><a href="root_comparison/elliptic_comparison.html">Comparison
|
||||
of Elliptic Integral Root Finding Algoritghms</a></span></dt>
|
||||
</dl></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 © 2006-2010, 2012-2014 Nikhar Agrawal,
|
||||
Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
|
||||
Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan Råde, Gautam Sewani,
|
||||
Benjamin Sobotta, 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="brent_minima.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots.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/cbrt_comparison.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,90 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Examples of Root-Finding (with and without derivatives)</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.5.1">
|
||||
<link rel="up" href="../roots.html" title="Root finding">
|
||||
<link rel="prev" href="roots_deriv.html" title="Root Finding With Derivatives: Newton-Raphson, Halley & Schröder">
|
||||
<link rel="next" href="root_finding_examples/cbrt_eg.html" title="Finding the Cubed Root 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_deriv.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots.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/cbrt_eg.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="math_toolkit.roots.root_finding_examples"></a><a class="link" href="root_finding_examples.html" title="Examples of Root-Finding (with and without derivatives)">Examples of
|
||||
Root-Finding (with and without derivatives)</a>
|
||||
</h3></div></div></div>
|
||||
<div class="toc"><dl class="toc">
|
||||
<dt><span class="section"><a href="root_finding_examples/cbrt_eg.html">Finding
|
||||
the Cubed Root With and Without Derivatives</a></span></dt>
|
||||
<dt><span class="section"><a href="root_finding_examples/lambda.html">Using
|
||||
C++11 Lambda's</a></span></dt>
|
||||
<dt><span class="section"><a href="root_finding_examples/5th_root_eg.html">Computing
|
||||
the Fifth Root</a></span></dt>
|
||||
<dt><span class="section"><a href="root_finding_examples/multiprecision_root.html">Root-finding
|
||||
using Boost.Multiprecision</a></span></dt>
|
||||
<dt><span class="section"><a href="root_finding_examples/nth_root.html">Generalizing
|
||||
to Compute the nth root</a></span></dt>
|
||||
<dt><span class="section"><a href="root_finding_examples/elliptic_eg.html">A
|
||||
More complex example - Inverting the Elliptic Integrals</a></span></dt>
|
||||
</dl></div>
|
||||
<p>
|
||||
The examples demonstrate how to use the various tools for <a href="http://en.wikipedia.org/wiki/Root-finding_algorithm" target="_top">root
|
||||
finding</a>.
|
||||
</p>
|
||||
<p>
|
||||
We start with the simple cube root function <code class="computeroutput"><span class="identifier">cbrt</span></code>
|
||||
( C++ standard function name <a href="http://en.cppreference.com/w/cpp/numeric/math/cbrt" target="_top">cbrt</a>)
|
||||
showing root finding <a class="link" href="root_finding_examples/cbrt_eg.html#math_toolkit.roots.root_finding_examples.cbrt_eg.cbrt_no_derivatives">without
|
||||
derivatives</a>.
|
||||
</p>
|
||||
<p>
|
||||
We then show how use of derivatives can improve the speed of convergence.
|
||||
</p>
|
||||
<p>
|
||||
(But these examples are only a demonstration and do not try to make the ultimate
|
||||
improvements of an 'industrial-strength' implementation, for example, of
|
||||
<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">cbrt</span></code>, mainly by using a better computed
|
||||
initial 'guess' at <a href="../../../../../../libs/math/include/boost/math/special_functions/cbrt.hpp" target="_top">cbrt.hpp</a>).
|
||||
</p>
|
||||
<p>
|
||||
Then we show how a higher root (<a class="link" href="root_finding_examples/5th_root_eg.html" title="Computing the Fifth Root">fifth
|
||||
root</a>) <sup>5</sup>√ can be computed, and in <a href="../../../../example/root_finding_n_example.cpp" target="_top">root_finding_n_example.cpp</a>
|
||||
a generic method for the <a class="link" href="root_finding_examples/nth_root.html" title="Generalizing to Compute the nth root">nth
|
||||
root</a> that constructs the derivatives at compile-time.
|
||||
</p>
|
||||
<p>
|
||||
These methods should be applicable to other functions that can be differentiated
|
||||
easily.
|
||||
</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 © 2006-2010, 2012-2014 Nikhar Agrawal,
|
||||
Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
|
||||
Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan Råde, Gautam Sewani,
|
||||
Benjamin Sobotta, 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_deriv.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots.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/cbrt_eg.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,169 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Computing the Fifth Root</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.5.1">
|
||||
<link rel="up" href="../root_finding_examples.html" title="Examples of Root-Finding (with and without derivatives)">
|
||||
<link rel="prev" href="lambda.html" title="Using C++11 Lambda's">
|
||||
<link rel="next" href="multiprecision_root.html" title="Root-finding using Boost.Multiprecision">
|
||||
</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="lambda.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../root_finding_examples.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="multiprecision_root.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="math_toolkit.roots.root_finding_examples.5th_root_eg"></a><a class="link" href="5th_root_eg.html" title="Computing the Fifth Root">Computing
|
||||
the Fifth Root</a>
|
||||
</h4></div></div></div>
|
||||
<p>
|
||||
Let's now suppose we want to find the <span class="bold"><strong>fifth root</strong></span>
|
||||
of a number <span class="emphasis"><em>a</em></span>.
|
||||
</p>
|
||||
<p>
|
||||
The equation we want to solve is :
|
||||
</p>
|
||||
<p>
|
||||
  <span class="emphasis"><em>f</em></span>(x) = <span class="emphasis"><em>x<sup>5</sup> -a</em></span>
|
||||
</p>
|
||||
<p>
|
||||
If your differentiation is a little rusty (or you are faced with an function
|
||||
whose complexity makes differentiation daunting), then you can get help,
|
||||
for example, from the invaluable <a href="http://www.wolframalpha.com/" target="_top">WolframAlpha
|
||||
site.</a>
|
||||
</p>
|
||||
<p>
|
||||
For example, entering the commmand: <code class="computeroutput"><span class="identifier">differentiate</span>
|
||||
<span class="identifier">x</span> <span class="special">^</span>
|
||||
<span class="number">5</span></code>
|
||||
</p>
|
||||
<p>
|
||||
or the Wolfram Language command: <code class="computeroutput"> <span class="identifier">D</span><span class="special">[</span><span class="identifier">x</span> <span class="special">^</span>
|
||||
<span class="number">5</span><span class="special">,</span> <span class="identifier">x</span><span class="special">]</span></code>
|
||||
</p>
|
||||
<p>
|
||||
gives the output: <code class="computeroutput"><span class="identifier">d</span><span class="special">/</span><span class="identifier">dx</span><span class="special">(</span><span class="identifier">x</span>
|
||||
<span class="special">^</span> <span class="number">5</span><span class="special">)</span> <span class="special">=</span> <span class="number">5</span>
|
||||
<span class="identifier">x</span> <span class="special">^</span>
|
||||
<span class="number">4</span></code>
|
||||
</p>
|
||||
<p>
|
||||
and to get the second differential, enter: <code class="computeroutput"><span class="identifier">second</span>
|
||||
<span class="identifier">differentiate</span> <span class="identifier">x</span>
|
||||
<span class="special">^</span> <span class="number">5</span></code>
|
||||
</p>
|
||||
<p>
|
||||
or the Wolfram Language command: <code class="computeroutput"><span class="identifier">D</span><span class="special">[</span><span class="identifier">x</span> <span class="special">^</span>
|
||||
<span class="number">5</span><span class="special">,</span> <span class="special">{</span> <span class="identifier">x</span><span class="special">,</span>
|
||||
<span class="number">2</span> <span class="special">}]</span></code>
|
||||
</p>
|
||||
<p>
|
||||
to get the output: <code class="computeroutput"><span class="identifier">d</span> <span class="special">^</span>
|
||||
<span class="number">2</span> <span class="special">/</span> <span class="identifier">dx</span> <span class="special">^</span> <span class="number">2</span><span class="special">(</span><span class="identifier">x</span>
|
||||
<span class="special">^</span> <span class="number">5</span><span class="special">)</span> <span class="special">=</span> <span class="number">20</span>
|
||||
<span class="identifier">x</span> <span class="special">^</span>
|
||||
<span class="number">3</span></code>
|
||||
</p>
|
||||
<p>
|
||||
To get a reference value, we can enter: <code class="literal">fifth root 3126</code>
|
||||
</p>
|
||||
<p>
|
||||
or: <code class="computeroutput"><span class="identifier">N</span><span class="special">[</span><span class="number">3126</span> <span class="special">^</span> <span class="special">(</span><span class="number">1</span> <span class="special">/</span> <span class="number">5</span><span class="special">),</span> <span class="number">50</span><span class="special">]</span></code>
|
||||
</p>
|
||||
<p>
|
||||
to get a result with a precision of 50 decimal digits:
|
||||
</p>
|
||||
<p>
|
||||
5.0003199590478625588206333405631053401128722314376
|
||||
</p>
|
||||
<p>
|
||||
(We could also get a reference value using <a class="link" href="multiprecision_root.html" title="Root-finding using Boost.Multiprecision">multiprecision
|
||||
root</a>).
|
||||
</p>
|
||||
<p>
|
||||
The 1st and 2nd derivatives of x<sup>5</sup> are:
|
||||
</p>
|
||||
<p>
|
||||
  <span class="emphasis"><em>f</em></span>'(x) = 5x<sup>4</sup>
|
||||
</p>
|
||||
<p>
|
||||
  <span class="emphasis"><em>f</em></span>''(x) = 20x<sup>3</sup>
|
||||
</p>
|
||||
<p>
|
||||
Using these expressions for the derivatives, the functor is:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">fifth_functor_2deriv</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// Functor returning both 1st and 2nd derivatives.</span>
|
||||
<span class="identifier">fifth_functor_2deriv</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">to_find_root_of</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">a</span><span class="special">(</span><span class="identifier">to_find_root_of</span><span class="special">)</span>
|
||||
<span class="special">{</span> <span class="comment">/* Constructor stores value a to find root of, for example: */</span> <span class="special">}</span>
|
||||
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">x</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// Return both f(x) and f'(x) and f''(x).</span>
|
||||
<span class="identifier">T</span> <span class="identifier">fx</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"><</span><span class="number">5</span><span class="special">>(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">-</span> <span class="identifier">a</span><span class="special">;</span> <span class="comment">// Difference (estimate x^3 - value).</span>
|
||||
<span class="identifier">T</span> <span class="identifier">dx</span> <span class="special">=</span> <span class="number">5</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"><</span><span class="number">4</span><span class="special">>(</span><span class="identifier">x</span><span class="special">);</span> <span class="comment">// 1st derivative = 5x^4.</span>
|
||||
<span class="identifier">T</span> <span class="identifier">d2x</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">math</span><span class="special">::</span><span class="identifier">pow</span><span class="special"><</span><span class="number">3</span><span class="special">>(</span><span class="identifier">x</span><span class="special">);</span> <span class="comment">// 2nd derivative = 20 x^3</span>
|
||||
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">fx</span><span class="special">,</span> <span class="identifier">dx</span><span class="special">,</span> <span class="identifier">d2x</span><span class="special">);</span> <span class="comment">// 'return' fx, dx and d2x.</span>
|
||||
<span class="special">}</span>
|
||||
<span class="keyword">private</span><span class="special">:</span>
|
||||
<span class="identifier">T</span> <span class="identifier">a</span><span class="special">;</span> <span class="comment">// to be 'fifth_rooted'.</span>
|
||||
<span class="special">};</span> <span class="comment">// struct fifth_functor_2deriv</span>
|
||||
</pre>
|
||||
<p>
|
||||
Our fifth-root function is now:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">T</span> <span class="identifier">fifth_2deriv</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">x</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// return fifth root of x using 1st and 2nd derivatives and Halley.</span>
|
||||
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">std</span><span class="special">;</span> <span class="comment">// Help ADL of std functions.</span>
|
||||
<span class="keyword">using</span> <span class="keyword">namespace</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="comment">// for halley_iterate.</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">exponent</span><span class="special">;</span>
|
||||
<span class="identifier">frexp</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="special">&</span><span class="identifier">exponent</span><span class="special">);</span> <span class="comment">// Get exponent of z (ignore mantissa).</span>
|
||||
<span class="identifier">T</span> <span class="identifier">guess</span> <span class="special">=</span> <span class="identifier">ldexp</span><span class="special">(</span><span class="number">1.</span><span class="special">,</span> <span class="identifier">exponent</span> <span class="special">/</span> <span class="number">5</span><span class="special">);</span> <span class="comment">// Rough guess is to divide the exponent by five.</span>
|
||||
<span class="identifier">T</span> <span class="identifier">min</span> <span class="special">=</span> <span class="identifier">ldexp</span><span class="special">(</span><span class="number">0.5</span><span class="special">,</span> <span class="identifier">exponent</span> <span class="special">/</span> <span class="number">5</span><span class="special">);</span> <span class="comment">// Minimum possible value is half our guess.</span>
|
||||
<span class="identifier">T</span> <span class="identifier">max</span> <span class="special">=</span> <span class="identifier">ldexp</span><span class="special">(</span><span class="number">2.</span><span class="special">,</span> <span class="identifier">exponent</span> <span class="special">/</span> <span class="number">5</span><span class="special">);</span> <span class="comment">// Maximum possible value is twice our guess.</span>
|
||||
<span class="comment">// Stop when slightly more than one of the digits are correct:</span>
|
||||
<span class="keyword">const</span> <span class="keyword">int</span> <span class="identifier">digits</span> <span class="special">=</span> <span class="keyword">static_cast</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">digits</span> <span class="special">*</span> <span class="number">0.4</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">50</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">T</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">halley_iterate</span><span class="special">(</span><span class="identifier">fifth_functor_2deriv</span><span class="special"><</span><span class="identifier">T</span><span class="special">>(</span><span class="identifier">x</span><span class="special">),</span> <span class="identifier">guess</span><span class="special">,</span> <span class="identifier">min</span><span class="special">,</span> <span class="identifier">max</span><span class="special">,</span> <span class="identifier">digits</span><span class="special">,</span> <span class="identifier">it</span><span class="special">);</span>
|
||||
<span class="keyword">return</span> <span class="identifier">result</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
Full code of this example is at <a href="../../../../../example/root_finding_example.cpp" target="_top">root_finding_example.cpp</a>
|
||||
and <a href="../../../../../example/root_finding_n_example.cpp" target="_top">root_finding_n_example.cpp</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 © 2006-2010, 2012-2014 Nikhar Agrawal,
|
||||
Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
|
||||
Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan Råde, Gautam Sewani,
|
||||
Benjamin Sobotta, 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="lambda.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../root_finding_examples.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="multiprecision_root.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,486 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Finding the Cubed Root With and Without Derivatives</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.5.1">
|
||||
<link rel="up" href="../root_finding_examples.html" title="Examples of Root-Finding (with and without derivatives)">
|
||||
<link rel="prev" href="../root_finding_examples.html" title="Examples of Root-Finding (with and without derivatives)">
|
||||
<link rel="next" href="lambda.html" title="Using C++11 Lambda's">
|
||||
</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="../root_finding_examples.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../root_finding_examples.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="lambda.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="math_toolkit.roots.root_finding_examples.cbrt_eg"></a><a class="link" href="cbrt_eg.html" title="Finding the Cubed Root With and Without Derivatives">Finding
|
||||
the Cubed Root With and Without Derivatives</a>
|
||||
</h4></div></div></div>
|
||||
<p>
|
||||
First some <code class="computeroutput"><span class="preprocessor">#includes</span></code>
|
||||
that will be needed.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">tools</span><span class="special">/</span><span class="identifier">roots</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="comment">//using boost::math::policies::policy;</span>
|
||||
<span class="comment">//using boost::math::tools::newton_raphson_iterate;</span>
|
||||
<span class="comment">//using boost::math::tools::halley_iterate; //</span>
|
||||
<span class="comment">//using boost::math::tools::eps_tolerance; // Binary functor for specified number of bits.</span>
|
||||
<span class="comment">//using boost::math::tools::bracket_and_solve_root;</span>
|
||||
<span class="comment">//using boost::math::tools::toms748_solve;</span>
|
||||
|
||||
<span class="preprocessor">#include</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">special_functions</span><span class="special">/</span><span class="identifier">next</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// For float_distance.</span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">tuple</span><span class="special">></span> <span class="comment">// for std::tuple and std::make_tuple.</span>
|
||||
<span class="preprocessor">#include</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">special_functions</span><span class="special">/</span><span class="identifier">cbrt</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// For boost::math::cbrt.</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>
|
||||
For clarity, <code class="computeroutput"><span class="keyword">using</span></code> statements
|
||||
are provided to list what functions are being used in this example: you
|
||||
can, of course, partly or fully qualify the names in other ways. (For
|
||||
your application, you may wish to extract some parts into header files,
|
||||
but you should never use <code class="computeroutput"><span class="keyword">using</span></code>
|
||||
statements globally in header files).
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
<p>
|
||||
Let's suppose we want to find the root of a number <span class="emphasis"><em>a</em></span>,
|
||||
and to start, compute the cube root.
|
||||
</p>
|
||||
<p>
|
||||
So the equation we want to solve is:
|
||||
</p>
|
||||
<p>
|
||||
   <span class="emphasis"><em>f(x) = x³ -a</em></span>
|
||||
</p>
|
||||
<p>
|
||||
We will first solve this without using any information about the slope
|
||||
or curvature of the cube root function.
|
||||
</p>
|
||||
<p>
|
||||
Fortunately, the cube-root function is 'Really Well Behaved' in that it
|
||||
is monotonic and has only one root (we leave negative values 'as an exercise
|
||||
for the student').
|
||||
</p>
|
||||
<p>
|
||||
We then show how adding what we can know about this function, first just
|
||||
the slope or 1st derivative <span class="emphasis"><em>f'(x)</em></span>, will speed homing
|
||||
in on the solution.
|
||||
</p>
|
||||
<p>
|
||||
Lastly, we show how adding the curvature <span class="emphasis"><em>f''(x)</em></span> too
|
||||
will speed convergence even more.
|
||||
</p>
|
||||
<h4>
|
||||
<a name="math_toolkit.roots.root_finding_examples.cbrt_eg.h0"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.root_finding_examples.cbrt_eg.cbrt_no_derivatives"></a></span><a class="link" href="cbrt_eg.html#math_toolkit.roots.root_finding_examples.cbrt_eg.cbrt_no_derivatives">Cube
|
||||
root function without derivatives</a>
|
||||
</h4>
|
||||
<p>
|
||||
First we define a function object (functor):
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">cbrt_functor_noderiv</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// cube root of x using only function - no derivatives.</span>
|
||||
<span class="identifier">cbrt_functor_noderiv</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">to_find_root_of</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">a</span><span class="special">(</span><span class="identifier">to_find_root_of</span><span class="special">)</span>
|
||||
<span class="special">{</span> <span class="comment">/* Constructor just stores value a to find root of. */</span> <span class="special">}</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">&</span> <span class="identifier">x</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">fx</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">*</span><span class="identifier">x</span><span class="special">*</span><span class="identifier">x</span> <span class="special">-</span> <span class="identifier">a</span><span class="special">;</span> <span class="comment">// Difference (estimate x^3 - a).</span>
|
||||
<span class="keyword">return</span> <span class="identifier">fx</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
<span class="keyword">private</span><span class="special">:</span>
|
||||
<span class="identifier">T</span> <span class="identifier">a</span><span class="special">;</span> <span class="comment">// to be 'cube_rooted'.</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
Implementing the cube-root function itself is fairly trivial now: the hardest
|
||||
part is finding a good approximation to begin with. In this case we'll
|
||||
just divide the exponent by three. (There are better but more complex guess
|
||||
algorithms used in 'real life'.)
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">T</span> <span class="identifier">cbrt_noderiv</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">x</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// return cube root of x using bracket_and_solve (no derivatives).</span>
|
||||
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">std</span><span class="special">;</span> <span class="comment">// Help ADL of std functions.</span>
|
||||
<span class="keyword">using</span> <span class="keyword">namespace</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="comment">// For bracket_and_solve_root.</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">exponent</span><span class="special">;</span>
|
||||
<span class="identifier">frexp</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="special">&</span><span class="identifier">exponent</span><span class="special">);</span> <span class="comment">// Get exponent of z (ignore mantissa).</span>
|
||||
<span class="identifier">T</span> <span class="identifier">guess</span> <span class="special">=</span> <span class="identifier">ldexp</span><span class="special">(</span><span class="number">1.</span><span class="special">,</span> <span class="identifier">exponent</span><span class="special">/</span><span class="number">3</span><span class="special">);</span> <span class="comment">// Rough guess is to divide the exponent by three.</span>
|
||||
<span class="identifier">T</span> <span class="identifier">factor</span> <span class="special">=</span> <span class="number">2</span><span class="special">;</span> <span class="comment">// How big steps to take when searching.</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="comment">// Limit to maximum iterations.</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">// Initally our chosen max iterations, but updated with actual.</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">is_rising</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span> <span class="comment">// So if result if guess^3 is too low, then try increasing guess.</span>
|
||||
<span class="keyword">int</span> <span class="identifier">digits</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">digits</span><span class="special">;</span> <span class="comment">// Maximum possible binary digits accuracy for type T.</span>
|
||||
<span class="comment">// Some fraction of digits is used to control how accurate to try to make the result.</span>
|
||||
<span class="keyword">int</span> <span class="identifier">get_digits</span> <span class="special">=</span> <span class="identifier">digits</span> <span class="special">-</span> <span class="number">3</span><span class="special">;</span> <span class="comment">// We have to have a non-zero interval at each step, so</span>
|
||||
<span class="comment">// maximum accuracy is digits - 1. But we also have to</span>
|
||||
<span class="comment">// allow for inaccuracy in f(x), otherwise the last few</span>
|
||||
<span class="comment">// iterations just thrash around.</span>
|
||||
<span class="identifier">eps_tolerance</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">tol</span><span class="special">(</span><span class="identifier">get_digits</span><span class="special">);</span> <span class="comment">// Set the tolerance.</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">bracket_and_solve_root</span><span class="special">(</span><span class="identifier">cbrt_functor_noderiv</span><span class="special"><</span><span class="identifier">T</span><span class="special">>(</span><span class="identifier">x</span><span class="special">),</span> <span class="identifier">guess</span><span class="special">,</span> <span class="identifier">factor</span><span class="special">,</span> <span class="identifier">is_rising</span><span class="special">,</span> <span class="identifier">tol</span><span class="special">,</span> <span class="identifier">it</span><span class="special">);</span>
|
||||
<span class="keyword">return</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">first</span> <span class="special">+</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">r</span><span class="special">.</span><span class="identifier">first</span><span class="special">)/</span><span class="number">2</span><span class="special">;</span> <span class="comment">// Midway between brackets is our result, if necessary we could</span>
|
||||
<span class="comment">// return the result as an interval here.</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td align="left" valign="top">
|
||||
<p>
|
||||
The final parameter specifying a maximum number of iterations is optional.
|
||||
However, it defaults to <code class="computeroutput"><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="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">>::</span><span class="identifier">max</span><span class="special">)();</span></code> which is <code class="computeroutput"><span class="number">18446744073709551615</span></code>
|
||||
and is more than anyone would wish to wait for!
|
||||
</p>
|
||||
<p>
|
||||
So it may be wise to chose some reasonable estimate of how many iterations
|
||||
may be needed, In this case the function is so well behaved that we can
|
||||
chose a low value of 20.
|
||||
</p>
|
||||
<p>
|
||||
Internally when Boost.Math uses these functions, it sets the maximum
|
||||
iterations to <code class="computeroutput"><span class="identifier">policies</span><span class="special">::</span><span class="identifier">get_max_root_iterations</span><span class="special"><</span><span class="identifier">Policy</span><span class="special">>();</span></code>.
|
||||
</p>
|
||||
</td></tr>
|
||||
</table></div>
|
||||
<p>
|
||||
Should we have wished we can show how many iterations were used in <code class="computeroutput"><span class="identifier">bracket_and_solve_root</span></code> (this information
|
||||
is lost outside <code class="computeroutput"><span class="identifier">cbrt_noderiv</span></code>),
|
||||
for example with:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">if</span> <span class="special">(</span><span class="identifier">it</span> <span class="special">>=</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"><<</span> <span class="string">"Unable to locate solution in "</span> <span class="special"><<</span> <span class="identifier">maxit</span> <span class="special"><<</span> <span class="string">" iterations:"</span>
|
||||
<span class="string">" Current best guess is between "</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="string">" and "</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">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"><<</span> <span class="string">"Converged after "</span> <span class="special"><<</span> <span class="identifier">it</span> <span class="special"><<</span> <span class="string">" (from maximum of "</span> <span class="special"><<</span> <span class="identifier">maxit</span> <span class="special"><<</span> <span class="string">" iterations)."</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
for output like
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">Converged</span> <span class="identifier">after</span> <span class="number">11</span> <span class="special">(</span><span class="identifier">from</span> <span class="identifier">maximum</span> <span class="identifier">of</span> <span class="number">20</span> <span class="identifier">iterations</span><span class="special">).</span>
|
||||
</pre>
|
||||
<p>
|
||||
This snippet from <code class="computeroutput"><span class="identifier">main</span><span class="special">()</span></code> in <a href="../../../../../example/root_finding_example.cpp" target="_top">root_finding_example.cpp</a>
|
||||
shows how it can be used.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">try</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">double</span> <span class="identifier">threecubed</span> <span class="special">=</span> <span class="number">27.</span><span class="special">;</span> <span class="comment">// Value that has an *exactly representable* integer cube root.</span>
|
||||
<span class="keyword">double</span> <span class="identifier">threecubedp1</span> <span class="special">=</span> <span class="number">28.</span><span class="special">;</span> <span class="comment">// Value whose cube root is *not* exactly representable.</span>
|
||||
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"cbrt(28) "</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">cbrt</span><span class="special">(</span><span class="number">28.</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> <span class="comment">// boost::math:: version of cbrt.</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"std::cbrt(28) "</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cbrt</span><span class="special">(</span><span class="number">28.</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> <span class="comment">// std:: version of cbrt.</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span><span class="string">" cast double "</span> <span class="special"><<</span> <span class="keyword">static_cast</span><span class="special"><</span><span class="keyword">double</span><span class="special">>(</span><span class="number">3.0365889718756625194208095785056696355814539772481111</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
|
||||
|
||||
<span class="comment">// Cube root using bracketing:</span>
|
||||
<span class="keyword">double</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">cbrt_noderiv</span><span class="special">(</span><span class="identifier">threecubed</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="string">"cbrt_noderiv("</span> <span class="special"><<</span> <span class="identifier">threecubed</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="identifier">r</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
|
||||
<span class="identifier">r</span> <span class="special">=</span> <span class="identifier">cbrt_noderiv</span><span class="special">(</span><span class="identifier">threecubedp1</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="string">"cbrt_noderiv("</span> <span class="special"><<</span> <span class="identifier">threecubedp1</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="identifier">r</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
|
||||
</pre>
|
||||
<pre class="programlisting"> cbrt_noderiv(27) = 3
|
||||
cbrt_noderiv(28) = 3.0365889718756618
|
||||
</pre>
|
||||
<p>
|
||||
The result of <code class="computeroutput"><span class="identifier">bracket_and_solve_root</span></code>
|
||||
is a <a href="http://www.cplusplus.com/reference/utility/pair/" target="_top">pair</a>
|
||||
of values that could be displayed.
|
||||
</p>
|
||||
<p>
|
||||
The number of bits separating them can be found using <code class="computeroutput"><span class="identifier">float_distance</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">r</span><span class="special">.</span><span class="identifier">second</span><span class="special">)</span></code>. The distance is zero (closest representable)
|
||||
for 3<sup>3</sup> = 27 but <code class="computeroutput"><span class="identifier">float_distance</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">r</span><span class="special">.</span><span class="identifier">second</span><span class="special">)</span> <span class="special">=</span> <span class="number">3</span></code>
|
||||
for cube root of 28 with this function. The result (avoiding overflow)
|
||||
is midway between these two values.
|
||||
</p>
|
||||
<h4>
|
||||
<a name="math_toolkit.roots.root_finding_examples.cbrt_eg.h1"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.root_finding_examples.cbrt_eg.cbrt_1st_derivative"></a></span><a class="link" href="cbrt_eg.html#math_toolkit.roots.root_finding_examples.cbrt_eg.cbrt_1st_derivative">Cube
|
||||
root function with 1st derivative (slope)</a>
|
||||
</h4>
|
||||
<p>
|
||||
We now solve the same problem, but using more information about the function,
|
||||
to show how this can speed up finding the best estimate of the root.
|
||||
</p>
|
||||
<p>
|
||||
For the root function, the 1st differential (the slope of the tangent to
|
||||
a curve at any point) is known.
|
||||
</p>
|
||||
<p>
|
||||
This algorithm is similar to this <a href="http://en.wikipedia.org/wiki/Nth_root_algorithm" target="_top">nth
|
||||
root algorithm</a>.
|
||||
</p>
|
||||
<p>
|
||||
If you need some reminders, then <a href="http://en.wikipedia.org/wiki/Derivative#Derivatives_of_elementary_functions" target="_top">derivatives
|
||||
of elementary functions</a> may help.
|
||||
</p>
|
||||
<p>
|
||||
Using the rule that the derivative of <span class="emphasis"><em>x<sup>n</sup></em></span> for positive
|
||||
n (actually all nonzero n) is <span class="emphasis"><em>n x<sup>n-1</sup></em></span>, allows us to
|
||||
get the 1st differential as <span class="emphasis"><em>3x<sup>2</sup></em></span>.
|
||||
</p>
|
||||
<p>
|
||||
To see how this extra information is used to find a root, view <a href="http://en.wikipedia.org/wiki/Newton%27s_method" target="_top">Newton-Raphson
|
||||
iterations</a> and the <a href="http://en.wikipedia.org/wiki/Newton%27s_method#mediaviewer/File:NewtonIteration_Ani.gif" target="_top">animation</a>.
|
||||
</p>
|
||||
<p>
|
||||
We define a better functor <code class="computeroutput"><span class="identifier">cbrt_functor_deriv</span></code>
|
||||
that returns both the evaluation of the function to solve, along with its
|
||||
first derivative:
|
||||
</p>
|
||||
<p>
|
||||
To '<span class="emphasis"><em>return</em></span>' two values, we use a <a href="http://en.cppreference.com/w/cpp/utility/pair" target="_top">std::pair</a>
|
||||
of floating-point values.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">cbrt_functor_deriv</span>
|
||||
<span class="special">{</span> <span class="comment">// Functor also returning 1st derivative.</span>
|
||||
<span class="identifier">cbrt_functor_deriv</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">to_find_root_of</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">a</span><span class="special">(</span><span class="identifier">to_find_root_of</span><span class="special">)</span>
|
||||
<span class="special">{</span> <span class="comment">// Constructor stores value a to find root of,</span>
|
||||
<span class="comment">// for example: calling cbrt_functor_deriv<T>(a) to use to get cube root of a.</span>
|
||||
<span class="special">}</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">x</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// Return both f(x) and f'(x).</span>
|
||||
<span class="identifier">T</span> <span class="identifier">fx</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">*</span><span class="identifier">x</span><span class="special">*</span><span class="identifier">x</span> <span class="special">-</span> <span class="identifier">a</span><span class="special">;</span> <span class="comment">// Difference (estimate x^3 - value).</span>
|
||||
<span class="identifier">T</span> <span class="identifier">dx</span> <span class="special">=</span> <span class="number">3</span> <span class="special">*</span> <span class="identifier">x</span><span class="special">*</span><span class="identifier">x</span><span class="special">;</span> <span class="comment">// 1st derivative = 3x^2.</span>
|
||||
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_pair</span><span class="special">(</span><span class="identifier">fx</span><span class="special">,</span> <span class="identifier">dx</span><span class="special">);</span> <span class="comment">// 'return' both fx and dx.</span>
|
||||
<span class="special">}</span>
|
||||
<span class="keyword">private</span><span class="special">:</span>
|
||||
<span class="identifier">T</span> <span class="identifier">a</span><span class="special">;</span> <span class="comment">// Store value to be 'cube_rooted'.</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
Our cube root function is now:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">T</span> <span class="identifier">cbrt_deriv</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">x</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// return cube root of x using 1st derivative and Newton_Raphson.</span>
|
||||
<span class="keyword">using</span> <span class="keyword">namespace</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="keyword">int</span> <span class="identifier">exponent</span><span class="special">;</span>
|
||||
<span class="identifier">frexp</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="special">&</span><span class="identifier">exponent</span><span class="special">);</span> <span class="comment">// Get exponent of z (ignore mantissa).</span>
|
||||
<span class="identifier">T</span> <span class="identifier">guess</span> <span class="special">=</span> <span class="identifier">ldexp</span><span class="special">(</span><span class="number">1.</span><span class="special">,</span> <span class="identifier">exponent</span><span class="special">/</span><span class="number">3</span><span class="special">);</span> <span class="comment">// Rough guess is to divide the exponent by three.</span>
|
||||
<span class="identifier">T</span> <span class="identifier">min</span> <span class="special">=</span> <span class="identifier">ldexp</span><span class="special">(</span><span class="number">0.5</span><span class="special">,</span> <span class="identifier">exponent</span><span class="special">/</span><span class="number">3</span><span class="special">);</span> <span class="comment">// Minimum possible value is half our guess.</span>
|
||||
<span class="identifier">T</span> <span class="identifier">max</span> <span class="special">=</span> <span class="identifier">ldexp</span><span class="special">(</span><span class="number">2.</span><span class="special">,</span> <span class="identifier">exponent</span><span class="special">/</span><span class="number">3</span><span class="special">);</span> <span class="comment">// Maximum possible value is twice our guess.</span>
|
||||
<span class="keyword">const</span> <span class="keyword">int</span> <span class="identifier">digits</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">digits</span><span class="special">;</span> <span class="comment">// Maximum possible binary digits accuracy for type T.</span>
|
||||
<span class="keyword">int</span> <span class="identifier">get_digits</span> <span class="special">=</span> <span class="keyword">static_cast</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">digits</span> <span class="special">*</span> <span class="number">0.6</span><span class="special">);</span> <span class="comment">// Accuracy doubles with each step, so stop when we have</span>
|
||||
<span class="comment">// just over half the digits correct.</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">T</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">newton_raphson_iterate</span><span class="special">(</span><span class="identifier">cbrt_functor_deriv</span><span class="special"><</span><span class="identifier">T</span><span class="special">>(</span><span class="identifier">x</span><span class="special">),</span> <span class="identifier">guess</span><span class="special">,</span> <span class="identifier">min</span><span class="special">,</span> <span class="identifier">max</span><span class="special">,</span> <span class="identifier">get_digits</span><span class="special">,</span> <span class="identifier">it</span><span class="special">);</span>
|
||||
<span class="keyword">return</span> <span class="identifier">result</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
The result of <a href="../../../../../../../libs/math/include/boost/math/tools/roots.hpp" target="_top"><code class="computeroutput"><span class="identifier">newton_raphson_iterate</span></code></a> function
|
||||
is a single value.
|
||||
</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>
|
||||
There is a compromise between accuracy and speed when chosing the value
|
||||
of <code class="computeroutput"><span class="identifier">digits</span></code>. It is tempting
|
||||
to simply chose <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">digits</span></code>, but this may mean some inefficient
|
||||
and unnecessary iterations as the function thrashes around trying to
|
||||
locate the last bit. In theory, since the precision doubles with each
|
||||
step it is sufficient to stop when half the bits are correct: as the
|
||||
last step will have doubled that to full precision. Of course the function
|
||||
has no way to tell if that is actually the case unless it does one more
|
||||
step to be sure. In practice setting the precision to slightly more than
|
||||
<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">digits</span> <span class="special">/</span>
|
||||
<span class="number">2</span></code> is a good choice.
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
<p>
|
||||
Note that it is up to the caller of the function to check the iteration
|
||||
count after the call to see if iteration stoped as a result of running
|
||||
out of iterations rather than meeting the required precision.
|
||||
</p>
|
||||
<p>
|
||||
Using the test data in <a href="../../../../../test/test_cbrt.cpp" target="_top">/test/test_cbrt.cpp</a>
|
||||
this found the cube root exact to the last digit in every case, and in
|
||||
no more than 6 iterations at double precision. However, you will note that
|
||||
a high precision was used in this example, exactly what was warned against
|
||||
earlier on in these docs! In this particular case it is possible to compute
|
||||
<span class="emphasis"><em>f(x)</em></span> exactly and without undue cancellation error,
|
||||
so a high limit is not too much of an issue.
|
||||
</p>
|
||||
<p>
|
||||
However, reducing the limit to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">digits</span>
|
||||
<span class="special">*</span> <span class="number">2</span> <span class="special">/</span> <span class="number">3</span></code> gave
|
||||
full precision in all but one of the test cases (and that one was out by
|
||||
just one bit). The maximum number of iterations remained 6, but in most
|
||||
cases was reduced by one.
|
||||
</p>
|
||||
<p>
|
||||
Note also that the above code omits a probable optimization by computing
|
||||
z²
|
||||
and reusing it, omits error handling, and does not handle negative values
|
||||
of z correctly. (These are left as the customary exercise for the reader!)
|
||||
</p>
|
||||
<p>
|
||||
The <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">cbrt</span></code> function also includes these and
|
||||
other improvements: most importantly it uses a much better initial guess
|
||||
which reduces the iteration count to just 1 in almost all cases.
|
||||
</p>
|
||||
<h4>
|
||||
<a name="math_toolkit.roots.root_finding_examples.cbrt_eg.h2"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.root_finding_examples.cbrt_eg.cbrt_2_derivatives"></a></span><a class="link" href="cbrt_eg.html#math_toolkit.roots.root_finding_examples.cbrt_eg.cbrt_2_derivatives">Cube
|
||||
root with 1st & 2nd derivative (slope & curvature)</a>
|
||||
</h4>
|
||||
<p>
|
||||
Next we define yet another even better functor <code class="computeroutput"><span class="identifier">cbrt_functor_2deriv</span></code>
|
||||
that returns both the evaluation of the function to solve, along with its
|
||||
first <span class="bold"><strong>and second</strong></span> derivative:
|
||||
</p>
|
||||
<p>
|
||||
  <span class="emphasis"><em>f''(x) = 6x</em></span>
|
||||
</p>
|
||||
<p>
|
||||
using information about both slope and curvature to speed convergence.
|
||||
</p>
|
||||
<p>
|
||||
To <span class="emphasis"><em>'return'</em></span> three values, we use a <code class="computeroutput"><span class="identifier">tuple</span></code>
|
||||
of three floating-point values:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">cbrt_functor_2deriv</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// Functor returning both 1st and 2nd derivatives.</span>
|
||||
<span class="identifier">cbrt_functor_2deriv</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">to_find_root_of</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">a</span><span class="special">(</span><span class="identifier">to_find_root_of</span><span class="special">)</span>
|
||||
<span class="special">{</span> <span class="comment">// Constructor stores value a to find root of, for example:</span>
|
||||
<span class="comment">// calling cbrt_functor_2deriv<T>(x) to get cube root of x,</span>
|
||||
<span class="special">}</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">x</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// Return both f(x) and f'(x) and f''(x).</span>
|
||||
<span class="identifier">T</span> <span class="identifier">fx</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">*</span><span class="identifier">x</span><span class="special">*</span><span class="identifier">x</span> <span class="special">-</span> <span class="identifier">a</span><span class="special">;</span> <span class="comment">// Difference (estimate x^3 - value).</span>
|
||||
<span class="identifier">T</span> <span class="identifier">dx</span> <span class="special">=</span> <span class="number">3</span> <span class="special">*</span> <span class="identifier">x</span><span class="special">*</span><span class="identifier">x</span><span class="special">;</span> <span class="comment">// 1st derivative = 3x^2.</span>
|
||||
<span class="identifier">T</span> <span class="identifier">d2x</span> <span class="special">=</span> <span class="number">6</span> <span class="special">*</span> <span class="identifier">x</span><span class="special">;</span> <span class="comment">// 2nd derivative = 6x.</span>
|
||||
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">fx</span><span class="special">,</span> <span class="identifier">dx</span><span class="special">,</span> <span class="identifier">d2x</span><span class="special">);</span> <span class="comment">// 'return' fx, dx and d2x.</span>
|
||||
<span class="special">}</span>
|
||||
<span class="keyword">private</span><span class="special">:</span>
|
||||
<span class="identifier">T</span> <span class="identifier">a</span><span class="special">;</span> <span class="comment">// to be 'cube_rooted'.</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
Our cube root function is now:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">T</span> <span class="identifier">cbrt_2deriv</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">x</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// return cube root of x using 1st and 2nd derivatives and Halley.</span>
|
||||
<span class="comment">//using namespace std; // Help ADL of std functions.</span>
|
||||
<span class="keyword">using</span> <span class="keyword">namespace</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="keyword">int</span> <span class="identifier">exponent</span><span class="special">;</span>
|
||||
<span class="identifier">frexp</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="special">&</span><span class="identifier">exponent</span><span class="special">);</span> <span class="comment">// Get exponent of z (ignore mantissa).</span>
|
||||
<span class="identifier">T</span> <span class="identifier">guess</span> <span class="special">=</span> <span class="identifier">ldexp</span><span class="special">(</span><span class="number">1.</span><span class="special">,</span> <span class="identifier">exponent</span><span class="special">/</span><span class="number">3</span><span class="special">);</span> <span class="comment">// Rough guess is to divide the exponent by three.</span>
|
||||
<span class="identifier">T</span> <span class="identifier">min</span> <span class="special">=</span> <span class="identifier">ldexp</span><span class="special">(</span><span class="number">0.5</span><span class="special">,</span> <span class="identifier">exponent</span><span class="special">/</span><span class="number">3</span><span class="special">);</span> <span class="comment">// Minimum possible value is half our guess.</span>
|
||||
<span class="identifier">T</span> <span class="identifier">max</span> <span class="special">=</span> <span class="identifier">ldexp</span><span class="special">(</span><span class="number">2.</span><span class="special">,</span> <span class="identifier">exponent</span><span class="special">/</span><span class="number">3</span><span class="special">);</span> <span class="comment">// Maximum possible value is twice our guess.</span>
|
||||
<span class="keyword">const</span> <span class="keyword">int</span> <span class="identifier">digits</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">digits</span><span class="special">;</span> <span class="comment">// Maximum possible binary digits accuracy for type T.</span>
|
||||
<span class="comment">// digits used to control how accurate to try to make the result.</span>
|
||||
<span class="keyword">int</span> <span class="identifier">get_digits</span> <span class="special">=</span> <span class="keyword">static_cast</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">digits</span> <span class="special">*</span> <span class="number">0.4</span><span class="special">);</span> <span class="comment">// Accuracy triples with each step, so stop when just</span>
|
||||
<span class="comment">// over one third of the digits are correct.</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">T</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">halley_iterate</span><span class="special">(</span><span class="identifier">cbrt_functor_2deriv</span><span class="special"><</span><span class="identifier">T</span><span class="special">>(</span><span class="identifier">x</span><span class="special">),</span> <span class="identifier">guess</span><span class="special">,</span> <span class="identifier">min</span><span class="special">,</span> <span class="identifier">max</span><span class="special">,</span> <span class="identifier">get_digits</span><span class="special">,</span> <span class="identifier">maxit</span><span class="special">);</span>
|
||||
<span class="keyword">return</span> <span class="identifier">result</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
The function <code class="computeroutput"><span class="identifier">halley_iterate</span></code>
|
||||
also returns a single value, and the number of iterations will reveal if
|
||||
it met the convergence criterion set by <code class="computeroutput"><span class="identifier">get_digits</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
The no-derivative method gives a result of
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">cbrt_noderiv</span><span class="special">(</span><span class="number">28</span><span class="special">)</span> <span class="special">=</span> <span class="number">3.0365889718756618</span>
|
||||
</pre>
|
||||
<p>
|
||||
with a 3 bits distance between the bracketed values, whereas the derivative
|
||||
methods both converge to a single value
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">cbrt_2deriv</span><span class="special">(</span><span class="number">28</span><span class="special">)</span> <span class="special">=</span> <span class="number">3.0365889718756627</span>
|
||||
</pre>
|
||||
<p>
|
||||
which we can compare with the <a href="../../../../../../../libs/math/doc/html/math_toolkit/powers/cbrt.html" target="_top">boost::math::cbrt</a>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">cbrt</span><span class="special">(</span><span class="number">28</span><span class="special">)</span> <span class="special">=</span> <span class="number">3.0365889718756627</span>
|
||||
</pre>
|
||||
<p>
|
||||
Note that the iterations are set to stop at just one-half of full precision,
|
||||
and yet, even so, not one of the test cases had a single bit wrong. What's
|
||||
more, the maximum number of iterations was now just 4.
|
||||
</p>
|
||||
<p>
|
||||
Just to complete the picture, we could have called <a class="link" href="../roots_deriv.html#math_toolkit.roots.roots_deriv.schroder"><code class="computeroutput"><span class="identifier">schroder_iterate</span></code></a> in the last example:
|
||||
and in fact it makes no difference to the accuracy or number of iterations
|
||||
in this particular case. However, the relative performance of these two
|
||||
methods may vary depending upon the nature of <span class="emphasis"><em>f(x)</em></span>,
|
||||
and the accuracy to which the initial guess can be computed. There appear
|
||||
to be no generalisations that can be made except "try them and see".
|
||||
</p>
|
||||
<p>
|
||||
Finally, had we called <code class="computeroutput"><span class="identifier">cbrt</span></code>
|
||||
with <a href="http://shoup.net/ntl/doc/RR.txt" target="_top">NTL::RR</a> set to
|
||||
1000 bit precision (about 300 decimal digits), then full precision can
|
||||
be obtained with just 7 iterations. To put that in perspective, an increase
|
||||
in precision by a factor of 20, has less than doubled the number of iterations.
|
||||
That just goes to emphasise that most of the iterations are used up getting
|
||||
the first few digits correct: after that these methods can churn out further
|
||||
digits with remarkable efficiency.
|
||||
</p>
|
||||
<p>
|
||||
Or to put it another way: <span class="emphasis"><em>nothing beats a really good initial
|
||||
guess!</em></span>
|
||||
</p>
|
||||
<p>
|
||||
Full code of this example is at <a href="../../../../../example/root_finding_example.cpp" target="_top">root_finding_example.cpp</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 © 2006-2010, 2012-2014 Nikhar Agrawal,
|
||||
Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
|
||||
Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan Råde, Gautam Sewani,
|
||||
Benjamin Sobotta, 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="../root_finding_examples.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../root_finding_examples.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="lambda.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,272 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>A More complex example - Inverting the Elliptic Integrals</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.5.1">
|
||||
<link rel="up" href="../root_finding_examples.html" title="Examples of Root-Finding (with and without derivatives)">
|
||||
<link rel="prev" href="nth_root.html" title="Generalizing to Compute the nth root">
|
||||
<link rel="next" href="../bad_guess.html" title="The Effect of a Poor Initial Guess">
|
||||
</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="nth_root.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../root_finding_examples.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="../bad_guess.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="math_toolkit.roots.root_finding_examples.elliptic_eg"></a><a class="link" href="elliptic_eg.html" title="A More complex example - Inverting the Elliptic Integrals">A
|
||||
More complex example - Inverting the Elliptic Integrals</a>
|
||||
</h4></div></div></div>
|
||||
<p>
|
||||
The arc length of an ellipse with radii <span class="emphasis"><em>a</em></span> and <span class="emphasis"><em>b</em></span>
|
||||
is given by:
|
||||
</p>
|
||||
<pre class="programlisting">L(a, b) = 4aE(k)</pre>
|
||||
<p>
|
||||
with:
|
||||
</p>
|
||||
<pre class="programlisting">k = √(1 - b<sup>2</sup>/a<sup>2</sup>)</pre>
|
||||
<p>
|
||||
where <span class="emphasis"><em>E(k)</em></span> is the complete elliptic integral of the
|
||||
second kind - see <a class="link" href="../../ellint/ellint_2.html" title="Elliptic Integrals of the Second Kind - Legendre Form">ellint_2</a>.
|
||||
</p>
|
||||
<p>
|
||||
Let's suppose we know the arc length and one radii, we can then calculate
|
||||
the other radius by inverting the formula above. We'll begin by encoding
|
||||
the above formula into a functor that our root-finding algorithms can call.
|
||||
</p>
|
||||
<p>
|
||||
Note that while not completely obvious from the formula above, the function
|
||||
is completely symmetrical in the two radii - which can be interchanged
|
||||
at will - in this case we need to make sure that <code class="computeroutput"><span class="identifier">a</span>
|
||||
<span class="special">>=</span> <span class="identifier">b</span></code>
|
||||
so that we don't accidentally take the square root of a negative number:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span> <span class="special">=</span> <span class="keyword">double</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">elliptic_root_functor_noderiv</span>
|
||||
<span class="special">{</span> <span class="comment">// Nth root of x using only function - no derivatives.</span>
|
||||
<span class="identifier">elliptic_root_functor_noderiv</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">arc</span><span class="special">,</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">radius</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">m_arc</span><span class="special">(</span><span class="identifier">arc</span><span class="special">),</span> <span class="identifier">m_radius</span><span class="special">(</span><span class="identifier">radius</span><span class="special">)</span>
|
||||
<span class="special">{</span> <span class="comment">// Constructor just stores value a to find root of.</span>
|
||||
<span class="special">}</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">&</span> <span class="identifier">x</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">using</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">sqrt</span><span class="special">;</span>
|
||||
<span class="comment">// return the difference between required arc-length, and the calculated arc-length for an</span>
|
||||
<span class="comment">// ellipse with radii m_radius and x:</span>
|
||||
<span class="identifier">T</span> <span class="identifier">a</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">max</span><span class="special">)(</span><span class="identifier">m_radius</span><span class="special">,</span> <span class="identifier">x</span><span class="special">);</span>
|
||||
<span class="identifier">T</span> <span class="identifier">b</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">min</span><span class="special">)(</span><span class="identifier">m_radius</span><span class="special">,</span> <span class="identifier">x</span><span class="special">);</span>
|
||||
<span class="identifier">T</span> <span class="identifier">k</span> <span class="special">=</span> <span class="identifier">sqrt</span><span class="special">(</span><span class="number">1</span> <span class="special">-</span> <span class="identifier">b</span> <span class="special">*</span> <span class="identifier">b</span> <span class="special">/</span> <span class="special">(</span><span class="identifier">a</span> <span class="special">*</span> <span class="identifier">a</span><span class="special">));</span>
|
||||
<span class="keyword">return</span> <span class="number">4</span> <span class="special">*</span> <span class="identifier">a</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">ellint_2</span><span class="special">(</span><span class="identifier">k</span><span class="special">)</span> <span class="special">-</span> <span class="identifier">m_arc</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
<span class="keyword">private</span><span class="special">:</span>
|
||||
<span class="identifier">T</span> <span class="identifier">m_arc</span><span class="special">;</span> <span class="comment">// length of arc.</span>
|
||||
<span class="identifier">T</span> <span class="identifier">m_radius</span><span class="special">;</span> <span class="comment">// one of the two radii of the ellipse</span>
|
||||
<span class="special">};</span> <span class="comment">// template <class T> struct elliptic_root_functor_noderiv</span>
|
||||
</pre>
|
||||
<p>
|
||||
We'll also need a decent estimate to start searching from, the approximation:
|
||||
</p>
|
||||
<pre class="programlisting">L(a, b) ≈ 4√(a<sup>2</sup> + b<sup>2</sup>)</pre>
|
||||
<p>
|
||||
Is easily inverted to give us what we need, which using derivative-free
|
||||
root finding leads to the algorithm:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span> <span class="special">=</span> <span class="keyword">double</span><span class="special">></span>
|
||||
<span class="identifier">T</span> <span class="identifier">elliptic_root_noderiv</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">radius</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">arc</span><span class="special">)</span>
|
||||
<span class="special">{</span> <span class="comment">// return the other radius of an ellipse, given one radii and the arc-length</span>
|
||||
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">std</span><span class="special">;</span> <span class="comment">// Help ADL of std functions.</span>
|
||||
<span class="keyword">using</span> <span class="keyword">namespace</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="comment">// For bracket_and_solve_root.</span>
|
||||
|
||||
<span class="identifier">T</span> <span class="identifier">guess</span> <span class="special">=</span> <span class="identifier">sqrt</span><span class="special">(</span><span class="identifier">arc</span> <span class="special">*</span> <span class="identifier">arc</span> <span class="special">/</span> <span class="number">16</span> <span class="special">-</span> <span class="identifier">radius</span> <span class="special">*</span> <span class="identifier">radius</span><span class="special">);</span>
|
||||
<span class="identifier">T</span> <span class="identifier">factor</span> <span class="special">=</span> <span class="number">1.2</span><span class="special">;</span> <span class="comment">// How big steps to take when searching.</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">50</span><span class="special">;</span> <span class="comment">// Limit to maximum iterations.</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">// Initally our chosen max iterations, but updated with actual.</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">is_rising</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span> <span class="comment">// arc-length increases if one radii increases, so function is rising</span>
|
||||
<span class="comment">// Define a termination condition, stop when nearly all digits are correct, but allow for</span>
|
||||
<span class="comment">// the fact that we are returning a range, and must have some inaccuracy in the elliptic integral:</span>
|
||||
<span class="identifier">eps_tolerance</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">tol</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">digits</span> <span class="special">-</span> <span class="number">2</span><span class="special">);</span>
|
||||
<span class="comment">// Call bracket_and_solve_root to find the solution, note that this is a rising function:</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">bracket_and_solve_root</span><span class="special">(</span><span class="identifier">elliptic_root_functor_noderiv</span><span class="special"><</span><span class="identifier">T</span><span class="special">>(</span><span class="identifier">arc</span><span class="special">,</span> <span class="identifier">radius</span><span class="special">),</span> <span class="identifier">guess</span><span class="special">,</span> <span class="identifier">factor</span><span class="special">,</span> <span class="identifier">is_rising</span><span class="special">,</span> <span class="identifier">tol</span><span class="special">,</span> <span class="identifier">it</span><span class="special">);</span>
|
||||
<span class="comment">// Result is midway between the endpoints of the range:</span>
|
||||
<span class="keyword">return</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">first</span> <span class="special">+</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">r</span><span class="special">.</span><span class="identifier">first</span><span class="special">)</span> <span class="special">/</span> <span class="number">2</span><span class="special">;</span>
|
||||
<span class="special">}</span> <span class="comment">// template <class T> T elliptic_root_noderiv(T x)</span>
|
||||
</pre>
|
||||
<p>
|
||||
This function generally finds the root within 8-10 iterations, so given
|
||||
that the runtime is completely dominated by the cost of calling the ellliptic
|
||||
integral it would be nice to reduce that count somewhat. We'll try to do
|
||||
that by using a derivative-based method; the derivatives of this function
|
||||
are rather hard to work out by hand, but fortunately <a href="http://www.wolframalpha.com/input/?i=d%2Fda+%5b4+*+a+*+EllipticE%281+-+b%5e2%2Fa%5e2%29%5d" target="_top">Wolfram
|
||||
Alpha</a> can do the grunt work for us to give:
|
||||
</p>
|
||||
<pre class="programlisting">d/da L(a, b) = 4(a<sup>2</sup>E(k) - b<sup>2</sup>K(k)) / (a<sup>2</sup> - b<sup>2</sup>)</pre>
|
||||
<p>
|
||||
Note that now we have <span class="bold"><strong>two</strong></span> elliptic integral
|
||||
calls to get the derivative, so our functor will be at least twice as expensive
|
||||
to call as the derivative-free one above: we'll have to reduce the iteration
|
||||
count quite substantially to make a difference!
|
||||
</p>
|
||||
<p>
|
||||
Here's the revised functor:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span> <span class="special">=</span> <span class="keyword">double</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">elliptic_root_functor_1deriv</span>
|
||||
<span class="special">{</span> <span class="comment">// Functor also returning 1st derviative.</span>
|
||||
<span class="identifier">BOOST_STATIC_ASSERT_MSG</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_integral</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value</span> <span class="special">==</span> <span class="keyword">false</span><span class="special">,</span> <span class="string">"Only floating-point type types can be used!"</span><span class="special">);</span>
|
||||
|
||||
<span class="identifier">elliptic_root_functor_1deriv</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">arc</span><span class="special">,</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">radius</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">m_arc</span><span class="special">(</span><span class="identifier">arc</span><span class="special">),</span> <span class="identifier">m_radius</span><span class="special">(</span><span class="identifier">radius</span><span class="special">)</span>
|
||||
<span class="special">{</span> <span class="comment">// Constructor just stores value a to find root of.</span>
|
||||
<span class="special">}</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">x</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">using</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">sqrt</span><span class="special">;</span>
|
||||
<span class="comment">// Return the difference between required arc-length, and the calculated arc-length for an</span>
|
||||
<span class="comment">// ellipse with radii m_radius and x, plus it's derivative.</span>
|
||||
<span class="comment">// See http://www.wolframalpha.com/input/?i=d%2Fda+[4+*+a+*+EllipticE%281+-+b^2%2Fa^2%29]</span>
|
||||
<span class="comment">// We require two elliptic integral calls, but from these we can calculate both</span>
|
||||
<span class="comment">// the function and it's derivative:</span>
|
||||
<span class="identifier">T</span> <span class="identifier">a</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">max</span><span class="special">)(</span><span class="identifier">m_radius</span><span class="special">,</span> <span class="identifier">x</span><span class="special">);</span>
|
||||
<span class="identifier">T</span> <span class="identifier">b</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">min</span><span class="special">)(</span><span class="identifier">m_radius</span><span class="special">,</span> <span class="identifier">x</span><span class="special">);</span>
|
||||
<span class="identifier">T</span> <span class="identifier">a2</span> <span class="special">=</span> <span class="identifier">a</span> <span class="special">*</span> <span class="identifier">a</span><span class="special">;</span>
|
||||
<span class="identifier">T</span> <span class="identifier">b2</span> <span class="special">=</span> <span class="identifier">b</span> <span class="special">*</span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">T</span> <span class="identifier">k</span> <span class="special">=</span> <span class="identifier">sqrt</span><span class="special">(</span><span class="number">1</span> <span class="special">-</span> <span class="identifier">b2</span> <span class="special">/</span> <span class="identifier">a2</span><span class="special">);</span>
|
||||
<span class="identifier">T</span> <span class="identifier">Ek</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">ellint_2</span><span class="special">(</span><span class="identifier">k</span><span class="special">);</span>
|
||||
<span class="identifier">T</span> <span class="identifier">Kk</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">ellint_1</span><span class="special">(</span><span class="identifier">k</span><span class="special">);</span>
|
||||
<span class="identifier">T</span> <span class="identifier">fx</span> <span class="special">=</span> <span class="number">4</span> <span class="special">*</span> <span class="identifier">a</span> <span class="special">*</span> <span class="identifier">Ek</span> <span class="special">-</span> <span class="identifier">m_arc</span><span class="special">;</span>
|
||||
<span class="identifier">T</span> <span class="identifier">dfx</span> <span class="special">=</span> <span class="number">4</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">a2</span> <span class="special">*</span> <span class="identifier">Ek</span> <span class="special">-</span> <span class="identifier">b2</span> <span class="special">*</span> <span class="identifier">Kk</span><span class="special">)</span> <span class="special">/</span> <span class="special">(</span><span class="identifier">a2</span> <span class="special">-</span> <span class="identifier">b2</span><span class="special">);</span>
|
||||
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_pair</span><span class="special">(</span><span class="identifier">fx</span><span class="special">,</span> <span class="identifier">dfx</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
<span class="keyword">private</span><span class="special">:</span>
|
||||
<span class="identifier">T</span> <span class="identifier">m_arc</span><span class="special">;</span> <span class="comment">// length of arc.</span>
|
||||
<span class="identifier">T</span> <span class="identifier">m_radius</span><span class="special">;</span> <span class="comment">// one of the two radii of the ellipse</span>
|
||||
<span class="special">};</span> <span class="comment">// struct elliptic_root__functor_1deriv</span>
|
||||
</pre>
|
||||
<p>
|
||||
The root-finding code is now almost the same as before, but we'll make
|
||||
use of Newton-iteration to get the result:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span> <span class="special">=</span> <span class="keyword">double</span><span class="special">></span>
|
||||
<span class="identifier">T</span> <span class="identifier">elliptic_root_1deriv</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">radius</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">arc</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">std</span><span class="special">;</span> <span class="comment">// Help ADL of std functions.</span>
|
||||
<span class="keyword">using</span> <span class="keyword">namespace</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="comment">// For newton_raphson_iterate.</span>
|
||||
|
||||
<span class="identifier">BOOST_STATIC_ASSERT_MSG</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_integral</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value</span> <span class="special">==</span> <span class="keyword">false</span><span class="special">,</span> <span class="string">"Only floating-point type types can be used!"</span><span class="special">);</span>
|
||||
|
||||
<span class="identifier">T</span> <span class="identifier">guess</span> <span class="special">=</span> <span class="identifier">sqrt</span><span class="special">(</span><span class="identifier">arc</span> <span class="special">*</span> <span class="identifier">arc</span> <span class="special">/</span> <span class="number">16</span> <span class="special">-</span> <span class="identifier">radius</span> <span class="special">*</span> <span class="identifier">radius</span><span class="special">);</span>
|
||||
<span class="identifier">T</span> <span class="identifier">min</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="comment">// Minimum possible value is zero.</span>
|
||||
<span class="identifier">T</span> <span class="identifier">max</span> <span class="special">=</span> <span class="identifier">arc</span><span class="special">;</span> <span class="comment">// Maximum possible value is the arc length.</span>
|
||||
|
||||
<span class="comment">// Accuracy doubles at each step, so stop when just over half of the digits are</span>
|
||||
<span class="comment">// correct, and rely on that step to polish off the remainder:</span>
|
||||
<span class="keyword">int</span> <span class="identifier">get_digits</span> <span class="special">=</span> <span class="keyword">static_cast</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">digits</span> <span class="special">*</span> <span class="number">0.6</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">T</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">newton_raphson_iterate</span><span class="special">(</span><span class="identifier">elliptic_root_functor_1deriv</span><span class="special"><</span><span class="identifier">T</span><span class="special">>(</span><span class="identifier">arc</span><span class="special">,</span> <span class="identifier">radius</span><span class="special">),</span> <span class="identifier">guess</span><span class="special">,</span> <span class="identifier">min</span><span class="special">,</span> <span class="identifier">max</span><span class="special">,</span> <span class="identifier">get_digits</span><span class="special">,</span> <span class="identifier">it</span><span class="special">);</span>
|
||||
<span class="keyword">return</span> <span class="identifier">result</span><span class="special">;</span>
|
||||
<span class="special">}</span> <span class="comment">// T elliptic_root_1_deriv Newton-Raphson</span>
|
||||
</pre>
|
||||
<p>
|
||||
The number of iterations required for <code class="computeroutput"><span class="keyword">double</span></code>
|
||||
precision is now usually around 4 - so we've slightly more than halved
|
||||
the number of iterations, but made the functor twice as expensive to call!
|
||||
</p>
|
||||
<p>
|
||||
Interestingly though, the second derivative requires no more expensive
|
||||
elliptic integral calls than the first does, in other words it comes essentially
|
||||
"for free", in which case we might as well make use of it and
|
||||
use Halley-iteration. This is quite a typical situation when inverting
|
||||
special-functions. Here's the revised functor:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span> <span class="special">=</span> <span class="keyword">double</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">elliptic_root_functor_2deriv</span>
|
||||
<span class="special">{</span> <span class="comment">// Functor returning both 1st and 2nd derivatives.</span>
|
||||
<span class="identifier">BOOST_STATIC_ASSERT_MSG</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_integral</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value</span> <span class="special">==</span> <span class="keyword">false</span><span class="special">,</span> <span class="string">"Only floating-point type types can be used!"</span><span class="special">);</span>
|
||||
|
||||
<span class="identifier">elliptic_root_functor_2deriv</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">arc</span><span class="special">,</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">radius</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">m_arc</span><span class="special">(</span><span class="identifier">arc</span><span class="special">),</span> <span class="identifier">m_radius</span><span class="special">(</span><span class="identifier">radius</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">x</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">using</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">sqrt</span><span class="special">;</span>
|
||||
<span class="comment">// Return the difference between required arc-length, and the calculated arc-length for an</span>
|
||||
<span class="comment">// ellipse with radii m_radius and x, plus it's derivative.</span>
|
||||
<span class="comment">// See http://www.wolframalpha.com/input/?i=d^2%2Fda^2+[4+*+a+*+EllipticE%281+-+b^2%2Fa^2%29]</span>
|
||||
<span class="comment">// for the second derivative.</span>
|
||||
<span class="identifier">T</span> <span class="identifier">a</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">max</span><span class="special">)(</span><span class="identifier">m_radius</span><span class="special">,</span> <span class="identifier">x</span><span class="special">);</span>
|
||||
<span class="identifier">T</span> <span class="identifier">b</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">min</span><span class="special">)(</span><span class="identifier">m_radius</span><span class="special">,</span> <span class="identifier">x</span><span class="special">);</span>
|
||||
<span class="identifier">T</span> <span class="identifier">a2</span> <span class="special">=</span> <span class="identifier">a</span> <span class="special">*</span> <span class="identifier">a</span><span class="special">;</span>
|
||||
<span class="identifier">T</span> <span class="identifier">b2</span> <span class="special">=</span> <span class="identifier">b</span> <span class="special">*</span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">T</span> <span class="identifier">k</span> <span class="special">=</span> <span class="identifier">sqrt</span><span class="special">(</span><span class="number">1</span> <span class="special">-</span> <span class="identifier">b2</span> <span class="special">/</span> <span class="identifier">a2</span><span class="special">);</span>
|
||||
<span class="identifier">T</span> <span class="identifier">Ek</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">ellint_2</span><span class="special">(</span><span class="identifier">k</span><span class="special">);</span>
|
||||
<span class="identifier">T</span> <span class="identifier">Kk</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">ellint_1</span><span class="special">(</span><span class="identifier">k</span><span class="special">);</span>
|
||||
<span class="identifier">T</span> <span class="identifier">fx</span> <span class="special">=</span> <span class="number">4</span> <span class="special">*</span> <span class="identifier">a</span> <span class="special">*</span> <span class="identifier">Ek</span> <span class="special">-</span> <span class="identifier">m_arc</span><span class="special">;</span>
|
||||
<span class="identifier">T</span> <span class="identifier">dfx</span> <span class="special">=</span> <span class="number">4</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">a2</span> <span class="special">*</span> <span class="identifier">Ek</span> <span class="special">-</span> <span class="identifier">b2</span> <span class="special">*</span> <span class="identifier">Kk</span><span class="special">)</span> <span class="special">/</span> <span class="special">(</span><span class="identifier">a2</span> <span class="special">-</span> <span class="identifier">b2</span><span class="special">);</span>
|
||||
<span class="identifier">T</span> <span class="identifier">dfx2</span> <span class="special">=</span> <span class="number">4</span> <span class="special">*</span> <span class="identifier">b2</span> <span class="special">*</span> <span class="special">((</span><span class="identifier">a2</span> <span class="special">+</span> <span class="identifier">b2</span><span class="special">)</span> <span class="special">*</span> <span class="identifier">Kk</span> <span class="special">-</span> <span class="number">2</span> <span class="special">*</span> <span class="identifier">a2</span> <span class="special">*</span> <span class="identifier">Ek</span><span class="special">)</span> <span class="special">/</span> <span class="special">(</span><span class="identifier">a</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">a2</span> <span class="special">-</span> <span class="identifier">b2</span><span class="special">)</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">a2</span> <span class="special">-</span> <span class="identifier">b2</span><span class="special">));</span>
|
||||
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">fx</span><span class="special">,</span> <span class="identifier">dfx</span><span class="special">,</span> <span class="identifier">dfx2</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
<span class="keyword">private</span><span class="special">:</span>
|
||||
<span class="identifier">T</span> <span class="identifier">m_arc</span><span class="special">;</span> <span class="comment">// length of arc.</span>
|
||||
<span class="identifier">T</span> <span class="identifier">m_radius</span><span class="special">;</span> <span class="comment">// one of the two radii of the ellipse</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
The actual root-finding code is almost the same as before, except we can
|
||||
use Halley, rather than Newton iteration:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span> <span class="special">=</span> <span class="keyword">double</span><span class="special">></span>
|
||||
<span class="identifier">T</span> <span class="identifier">elliptic_root_2deriv</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">radius</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">arc</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">std</span><span class="special">;</span> <span class="comment">// Help ADL of std functions.</span>
|
||||
<span class="keyword">using</span> <span class="keyword">namespace</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="comment">// For halley_iterate.</span>
|
||||
|
||||
<span class="identifier">BOOST_STATIC_ASSERT_MSG</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_integral</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value</span> <span class="special">==</span> <span class="keyword">false</span><span class="special">,</span> <span class="string">"Only floating-point type types can be used!"</span><span class="special">);</span>
|
||||
|
||||
<span class="identifier">T</span> <span class="identifier">guess</span> <span class="special">=</span> <span class="identifier">sqrt</span><span class="special">(</span><span class="identifier">arc</span> <span class="special">*</span> <span class="identifier">arc</span> <span class="special">/</span> <span class="number">16</span> <span class="special">-</span> <span class="identifier">radius</span> <span class="special">*</span> <span class="identifier">radius</span><span class="special">);</span>
|
||||
<span class="identifier">T</span> <span class="identifier">min</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="comment">// Minimum possible value is zero.</span>
|
||||
<span class="identifier">T</span> <span class="identifier">max</span> <span class="special">=</span> <span class="identifier">arc</span><span class="special">;</span> <span class="comment">// radius can't be larger than the arc length.</span>
|
||||
|
||||
<span class="comment">// Accuracy triples at each step, so stop when just over one-third of the digits</span>
|
||||
<span class="comment">// are correct, and the last iteration will polish off the remaining digits:</span>
|
||||
<span class="keyword">int</span> <span class="identifier">get_digits</span> <span class="special">=</span> <span class="keyword">static_cast</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">digits</span> <span class="special">*</span> <span class="number">0.4</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">T</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">halley_iterate</span><span class="special">(</span><span class="identifier">elliptic_root_functor_2deriv</span><span class="special"><</span><span class="identifier">T</span><span class="special">>(</span><span class="identifier">arc</span><span class="special">,</span> <span class="identifier">radius</span><span class="special">),</span> <span class="identifier">guess</span><span class="special">,</span> <span class="identifier">min</span><span class="special">,</span> <span class="identifier">max</span><span class="special">,</span> <span class="identifier">get_digits</span><span class="special">,</span> <span class="identifier">it</span><span class="special">);</span>
|
||||
<span class="keyword">return</span> <span class="identifier">result</span><span class="special">;</span>
|
||||
<span class="special">}</span> <span class="comment">// nth_2deriv Halley</span>
|
||||
</pre>
|
||||
<p>
|
||||
While this function uses only slightly fewer iterations (typically around
|
||||
3) to find the root, compared to the original derivative-free method, we've
|
||||
moved from 8-10 elliptic integral calls to 6.
|
||||
</p>
|
||||
<p>
|
||||
Full code of this example is at <a href="../../../../../example/root_elliptic_finding.cpp" target="_top">root_elliptic_finding.cpp</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 © 2006-2010, 2012-2014 Nikhar Agrawal,
|
||||
Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
|
||||
Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan Råde, Gautam Sewani,
|
||||
Benjamin Sobotta, 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="nth_root.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../root_finding_examples.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="../bad_guess.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,78 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Using C++11 Lambda's</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.5.1">
|
||||
<link rel="up" href="../root_finding_examples.html" title="Examples of Root-Finding (with and without derivatives)">
|
||||
<link rel="prev" href="cbrt_eg.html" title="Finding the Cubed Root With and Without Derivatives">
|
||||
<link rel="next" href="5th_root_eg.html" title="Computing the Fifth Root">
|
||||
</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="cbrt_eg.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../root_finding_examples.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="5th_root_eg.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="math_toolkit.roots.root_finding_examples.lambda"></a><a class="link" href="lambda.html" title="Using C++11 Lambda's">Using
|
||||
C++11 Lambda's</a>
|
||||
</h4></div></div></div>
|
||||
<p>
|
||||
Since all the root finding functions accept a function-object, they can
|
||||
be made to work (often in a lot less code) with C++11 lambda's. Here's
|
||||
the much reduced code for our "toy" cube root function:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">T</span> <span class="identifier">cbrt_2deriv_lambda</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">x</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// return cube root of x using 1st and 2nd derivatives and Halley.</span>
|
||||
<span class="comment">//using namespace std; // Help ADL of std functions.</span>
|
||||
<span class="keyword">using</span> <span class="keyword">namespace</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="keyword">int</span> <span class="identifier">exponent</span><span class="special">;</span>
|
||||
<span class="identifier">frexp</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="special">&</span><span class="identifier">exponent</span><span class="special">);</span> <span class="comment">// Get exponent of z (ignore mantissa).</span>
|
||||
<span class="identifier">T</span> <span class="identifier">guess</span> <span class="special">=</span> <span class="identifier">ldexp</span><span class="special">(</span><span class="number">1.</span><span class="special">,</span> <span class="identifier">exponent</span> <span class="special">/</span> <span class="number">3</span><span class="special">);</span> <span class="comment">// Rough guess is to divide the exponent by three.</span>
|
||||
<span class="identifier">T</span> <span class="identifier">min</span> <span class="special">=</span> <span class="identifier">ldexp</span><span class="special">(</span><span class="number">0.5</span><span class="special">,</span> <span class="identifier">exponent</span> <span class="special">/</span> <span class="number">3</span><span class="special">);</span> <span class="comment">// Minimum possible value is half our guess.</span>
|
||||
<span class="identifier">T</span> <span class="identifier">max</span> <span class="special">=</span> <span class="identifier">ldexp</span><span class="special">(</span><span class="number">2.</span><span class="special">,</span> <span class="identifier">exponent</span> <span class="special">/</span> <span class="number">3</span><span class="special">);</span> <span class="comment">// Maximum possible value is twice our guess.</span>
|
||||
<span class="keyword">const</span> <span class="keyword">int</span> <span class="identifier">digits</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">digits</span><span class="special">;</span> <span class="comment">// Maximum possible binary digits accuracy for type T.</span>
|
||||
<span class="comment">// digits used to control how accurate to try to make the result.</span>
|
||||
<span class="keyword">int</span> <span class="identifier">get_digits</span> <span class="special">=</span> <span class="keyword">static_cast</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">digits</span> <span class="special">*</span> <span class="number">0.4</span><span class="special">);</span> <span class="comment">// Accuracy triples with each step, so stop when just</span>
|
||||
<span class="comment">// over one third of the digits are correct.</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">T</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">halley_iterate</span><span class="special">(</span>
|
||||
<span class="comment">// lambda function:</span>
|
||||
<span class="special">[</span><span class="identifier">x</span><span class="special">](</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">g</span><span class="special">){</span> <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">g</span> <span class="special">*</span> <span class="identifier">g</span> <span class="special">*</span> <span class="identifier">g</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="identifier">g</span> <span class="special">*</span> <span class="identifier">g</span><span class="special">,</span> <span class="number">6</span> <span class="special">*</span> <span class="identifier">g</span><span class="special">);</span> <span class="special">},</span>
|
||||
<span class="identifier">guess</span><span class="special">,</span> <span class="identifier">min</span><span class="special">,</span> <span class="identifier">max</span><span class="special">,</span> <span class="identifier">get_digits</span><span class="special">,</span> <span class="identifier">maxit</span><span class="special">);</span>
|
||||
<span class="keyword">return</span> <span class="identifier">result</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
Full code of this example is at <a href="../../../../../example/root_finding_example.cpp" target="_top">root_finding_example.cpp</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 © 2006-2010, 2012-2014 Nikhar Agrawal,
|
||||
Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
|
||||
Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan Råde, Gautam Sewani,
|
||||
Benjamin Sobotta, 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="cbrt_eg.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../root_finding_examples.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="5th_root_eg.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,291 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Root-finding using Boost.Multiprecision</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.5.1">
|
||||
<link rel="up" href="../root_finding_examples.html" title="Examples of Root-Finding (with and without derivatives)">
|
||||
<link rel="prev" href="5th_root_eg.html" title="Computing the Fifth Root">
|
||||
<link rel="next" href="nth_root.html" title="Generalizing to Compute the nth root">
|
||||
</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="5th_root_eg.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../root_finding_examples.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="nth_root.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="math_toolkit.roots.root_finding_examples.multiprecision_root"></a><a class="link" href="multiprecision_root.html" title="Root-finding using Boost.Multiprecision">Root-finding
|
||||
using Boost.Multiprecision</a>
|
||||
</h4></div></div></div>
|
||||
<p>
|
||||
The apocryphally astute reader might, by now, be asking "How do we
|
||||
know if this computes the 'right' answer?".
|
||||
</p>
|
||||
<p>
|
||||
For most values, there is, sadly, no 'right' answer. This is because values
|
||||
can only rarely be <span class="emphasis"><em>exactly represented</em></span> by C++ floating-point
|
||||
types. What we do want is the 'best' representation - one that is the nearest
|
||||
<a href="http://en.wikipedia.org/wiki/Floating_point#Representable_numbers.2C_conversion_and_rounding" target="_top">representable</a>
|
||||
value. (For more about how numbers are represented see <a href="http://en.wikipedia.org/wiki/Floating_point" target="_top">Floating
|
||||
point</a>).
|
||||
</p>
|
||||
<p>
|
||||
Of course, we might start with finding an external reference source like
|
||||
<a href="http://www.wolframalpha.com/" target="_top">Wolfram Alpha</a>, as above,
|
||||
but this is not always possible.
|
||||
</p>
|
||||
<p>
|
||||
Another way to reassure is to compute 'reference' values at higher precision
|
||||
with which to compare the results of our iterative computations using built-in
|
||||
like <code class="computeroutput"><span class="keyword">double</span></code>. They should agree
|
||||
within the tolerance that was set.
|
||||
</p>
|
||||
<p>
|
||||
The result of <code class="computeroutput"><span class="keyword">static_cast</span></code>ing
|
||||
to <code class="computeroutput"><span class="keyword">double</span></code> from a higher-precision
|
||||
type like <code class="computeroutput"><span class="identifier">cpp_bin_float_50</span></code>
|
||||
is guaranteed to be the <span class="bold"><strong>nearest representable</strong></span>
|
||||
<code class="computeroutput"><span class="keyword">double</span></code> value.
|
||||
</p>
|
||||
<p>
|
||||
For example, the cube root functions in our example for <code class="computeroutput"><span class="identifier">cbrt</span><span class="special">(</span><span class="number">28.</span><span class="special">)</span></code>
|
||||
compute
|
||||
</p>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cbrt</span><span class="special"><</span><span class="keyword">double</span><span class="special">>(</span><span class="number">28.</span><span class="special">)</span> <span class="special">=</span>
|
||||
<span class="number">3.0365889718756627</span></code>
|
||||
</p>
|
||||
<p>
|
||||
WolframAlpha says <code class="computeroutput"><span class="number">3.036588971875662519420809578505669635581453977248111123242141</span><span class="special">...</span></code>
|
||||
</p>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="keyword">static_cast</span><span class="special"><</span><span class="keyword">double</span><span class="special">>(</span><span class="number">3.03658897187566251942080957850</span><span class="special">)</span>
|
||||
<span class="special">=</span> <span class="number">3.0365889718756627</span></code>
|
||||
</p>
|
||||
<p>
|
||||
This example <code class="computeroutput"><span class="identifier">cbrt</span><span class="special">(</span><span class="number">28.</span><span class="special">)</span> <span class="special">=</span>
|
||||
<span class="number">3.0365889718756627</span></code>
|
||||
</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>
|
||||
To ensure that all potentially significant decimal digits are displayed
|
||||
use <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">max_digits10</span></code> (or if not available on
|
||||
older platforms or compilers use <code class="computeroutput"><span class="number">2</span><span class="special">+</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">double</span><span class="special">>::</span><span class="identifier">digits</span><span class="special">*</span><span class="number">3010</span><span class="special">/</span><span class="number">10000</span></code>).<br>
|
||||
</p>
|
||||
<p>
|
||||
Ideally, values should agree to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">-</span><span class="identifier">limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">digits10</span></code>
|
||||
decimal digits.
|
||||
</p>
|
||||
<p>
|
||||
This also means that a 'reference' value to be <span class="bold"><strong>input</strong></span>
|
||||
or <code class="computeroutput"><span class="keyword">static_cast</span></code> should have
|
||||
at least <code class="computeroutput"><span class="identifier">max_digits10</span></code>
|
||||
decimal digits (17 for 64-bit <code class="computeroutput"><span class="keyword">double</span></code>).
|
||||
</p>
|
||||
</td></tr>
|
||||
</table></div>
|
||||
<p>
|
||||
If we wish to compute <span class="bold"><strong>higher-precision values</strong></span>
|
||||
then, on some platforms, we may be able to use <code class="computeroutput"><span class="keyword">long</span>
|
||||
<span class="keyword">double</span></code> with a higher precision than
|
||||
<code class="computeroutput"><span class="keyword">double</span></code> to compare with the
|
||||
very common <code class="computeroutput"><span class="keyword">double</span></code> and/or
|
||||
a more efficient built-in quad floating-point type like <code class="computeroutput"><span class="identifier">__float128</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
Almost all platforms can easily use <a href="../../../../../../../libs/multiprecision/doc/html/index.html" target="_top">Boost.Multiprecision</a>,
|
||||
for example, <a href="../../../../../../../libs/multiprecision/doc/html/boost_multiprecision/tut/floats/cpp_dec_float.html" target="_top">cpp_dec_float</a>
|
||||
or a binary type <a href="../../../../../../../libs/multiprecision/doc/html/boost_multiprecision/tut/floats/cpp_bin_float.html" target="_top">cpp_bin_float</a>
|
||||
types, to compute values at very much higher precision.
|
||||
</p>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td align="left" valign="top"><p>
|
||||
With multiprecision types, it is debatable whether to use the type <code class="computeroutput"><span class="identifier">T</span></code> for computing the initial guesses.
|
||||
Type <code class="computeroutput"><span class="keyword">double</span></code> is like to be
|
||||
accurate enough for the method used in these examples. This would limit
|
||||
the exponent range of possible values to that of <code class="computeroutput"><span class="keyword">double</span></code>.
|
||||
There is also the cost of conversion to and from type <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
to consider. In these examples, <code class="computeroutput"><span class="keyword">double</span></code>
|
||||
is used via <code class="computeroutput"><span class="keyword">typedef</span> <span class="keyword">double</span>
|
||||
<span class="identifier">guess_type</span></code>.
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
<p>
|
||||
Since the functors and functions used above are templated on the value
|
||||
type, we can very simply use them with any of the <a href="../../../../../../../libs/multiprecision/doc/html/index.html" target="_top">Boost.Multiprecision</a>
|
||||
types. As a reminder, here's our toy cube root function using 2 derivatives
|
||||
and C++11 lambda functions to find the root:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">T</span> <span class="identifier">cbrt_2deriv_lambda</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">x</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// return cube root of x using 1st and 2nd derivatives and Halley.</span>
|
||||
<span class="comment">//using namespace std; // Help ADL of std functions.</span>
|
||||
<span class="keyword">using</span> <span class="keyword">namespace</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="keyword">int</span> <span class="identifier">exponent</span><span class="special">;</span>
|
||||
<span class="identifier">frexp</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="special">&</span><span class="identifier">exponent</span><span class="special">);</span> <span class="comment">// Get exponent of z (ignore mantissa).</span>
|
||||
<span class="identifier">T</span> <span class="identifier">guess</span> <span class="special">=</span> <span class="identifier">ldexp</span><span class="special">(</span><span class="number">1.</span><span class="special">,</span> <span class="identifier">exponent</span> <span class="special">/</span> <span class="number">3</span><span class="special">);</span> <span class="comment">// Rough guess is to divide the exponent by three.</span>
|
||||
<span class="identifier">T</span> <span class="identifier">min</span> <span class="special">=</span> <span class="identifier">ldexp</span><span class="special">(</span><span class="number">0.5</span><span class="special">,</span> <span class="identifier">exponent</span> <span class="special">/</span> <span class="number">3</span><span class="special">);</span> <span class="comment">// Minimum possible value is half our guess.</span>
|
||||
<span class="identifier">T</span> <span class="identifier">max</span> <span class="special">=</span> <span class="identifier">ldexp</span><span class="special">(</span><span class="number">2.</span><span class="special">,</span> <span class="identifier">exponent</span> <span class="special">/</span> <span class="number">3</span><span class="special">);</span> <span class="comment">// Maximum possible value is twice our guess.</span>
|
||||
<span class="keyword">const</span> <span class="keyword">int</span> <span class="identifier">digits</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">digits</span><span class="special">;</span> <span class="comment">// Maximum possible binary digits accuracy for type T.</span>
|
||||
<span class="comment">// digits used to control how accurate to try to make the result.</span>
|
||||
<span class="keyword">int</span> <span class="identifier">get_digits</span> <span class="special">=</span> <span class="keyword">static_cast</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">digits</span> <span class="special">*</span> <span class="number">0.4</span><span class="special">);</span> <span class="comment">// Accuracy triples with each step, so stop when just</span>
|
||||
<span class="comment">// over one third of the digits are correct.</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">T</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">halley_iterate</span><span class="special">(</span>
|
||||
<span class="comment">// lambda function:</span>
|
||||
<span class="special">[</span><span class="identifier">x</span><span class="special">](</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">g</span><span class="special">){</span> <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">g</span> <span class="special">*</span> <span class="identifier">g</span> <span class="special">*</span> <span class="identifier">g</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="identifier">g</span> <span class="special">*</span> <span class="identifier">g</span><span class="special">,</span> <span class="number">6</span> <span class="special">*</span> <span class="identifier">g</span><span class="special">);</span> <span class="special">},</span>
|
||||
<span class="identifier">guess</span><span class="special">,</span> <span class="identifier">min</span><span class="special">,</span> <span class="identifier">max</span><span class="special">,</span> <span class="identifier">get_digits</span><span class="special">,</span> <span class="identifier">maxit</span><span class="special">);</span>
|
||||
<span class="keyword">return</span> <span class="identifier">result</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
Some examples below are 50 decimal digit decimal and binary types (and
|
||||
on some platforms a much faster <code class="computeroutput"><span class="identifier">float128</span></code>
|
||||
or <code class="computeroutput"><span class="identifier">quad_float</span></code> type ) that
|
||||
we can use with these includes:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></span> <span class="comment">// For cpp_bin_float_50.</span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</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">></span> <span class="comment">// For cpp_dec_float_50.</span>
|
||||
<span class="preprocessor">#ifndef</span> <span class="identifier">_MSC_VER</span> <span class="comment">// float128 is not yet supported by Microsoft compiler at 2013.</span>
|
||||
<span class="preprocessor"># include</span> <span class="special"><</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="identifier">hpp</span><span class="special">></span> <span class="comment">// Requires libquadmath.</span>
|
||||
<span class="preprocessor">#endif</span>
|
||||
</pre>
|
||||
<p>
|
||||
Some using statements simplify their use:
|
||||
</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_dec_float_50</span><span class="special">;</span> <span class="comment">// decimal.</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_bin_float_50</span><span class="special">;</span> <span class="comment">// binary.</span>
|
||||
<span class="preprocessor">#ifndef</span> <span class="identifier">_MSC_VER</span> <span class="comment">// Not supported by Microsoft compiler.</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>
|
||||
They can be used 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"><</span><span class="identifier">cpp_dec_float_50</span><span class="special">>::</span><span class="identifier">digits10</span><span class="special">);</span>
|
||||
|
||||
<span class="identifier">cpp_dec_float_50</span> <span class="identifier">two</span> <span class="special">=</span> <span class="number">2</span><span class="special">;</span> <span class="comment">// </span>
|
||||
<span class="identifier">cpp_dec_float_50</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">cbrt_2deriv</span><span class="special">(</span><span class="identifier">two</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="string">"cbrt("</span> <span class="special"><<</span> <span class="identifier">two</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="identifier">r</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
|
||||
|
||||
<span class="identifier">r</span> <span class="special">=</span> <span class="identifier">cbrt_2deriv</span><span class="special">(</span><span class="number">2.</span><span class="special">);</span> <span class="comment">// Passing a double, so ADL will compute a double precision result.</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"cbrt("</span> <span class="special"><<</span> <span class="identifier">two</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="identifier">r</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
|
||||
<span class="comment">// cbrt(2) = 1.2599210498948731906665443602832965552806854248047 'wrong' from digits 17 onwards!</span>
|
||||
<span class="identifier">r</span> <span class="special">=</span> <span class="identifier">cbrt_2deriv</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">cpp_dec_float_50</span><span class="special">>(</span><span class="number">2.</span><span class="special">));</span> <span class="comment">// Passing a cpp_dec_float_50, </span>
|
||||
<span class="comment">// so will compute a cpp_dec_float_50 precision result.</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"cbrt("</span> <span class="special"><<</span> <span class="identifier">two</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="identifier">r</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
|
||||
<span class="identifier">r</span> <span class="special">=</span> <span class="identifier">cbrt_2deriv</span><span class="special"><</span><span class="identifier">cpp_dec_float_50</span><span class="special">>(</span><span class="number">2.</span><span class="special">);</span> <span class="comment">// Explictly a cpp_dec_float_50, so will compute a cpp_dec_float_50 precision result.</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"cbrt("</span> <span class="special"><<</span> <span class="identifier">two</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="identifier">r</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
|
||||
<span class="comment">// cpp_dec_float_50 1.2599210498948731647672106072782283505702514647015</span>
|
||||
</pre>
|
||||
<p>
|
||||
A reference value computed by <a href="http://www.wolframalpha.com/" target="_top">Wolfram
|
||||
Alpha</a> is
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">N</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="number">3</span><span class="special">),</span> <span class="number">50</span><span class="special">]</span> <span class="number">1.2599210498948731647672106072782283505702514647015</span>
|
||||
</pre>
|
||||
<p>
|
||||
which agrees exactly.
|
||||
</p>
|
||||
<p>
|
||||
To <span class="bold"><strong>show</strong></span> values to their full precision,
|
||||
it is necessary to adjust the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span></code>
|
||||
<code class="computeroutput"><span class="identifier">precision</span></code> to suit the type,
|
||||
for example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">T</span> <span class="identifier">show_cube_root</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">value</span><span class="special">)</span>
|
||||
<span class="special">{</span> <span class="comment">// Demonstrate by printing the root using all definitely significant digits.</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"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">digits10</span><span class="special">);</span>
|
||||
<span class="identifier">T</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">cbrt_2deriv</span><span class="special">(</span><span class="identifier">value</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="string">"value = "</span> <span class="special"><<</span> <span class="identifier">value</span> <span class="special"><<</span> <span class="string">", cube root ="</span> <span class="special"><<</span> <span class="identifier">r</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
|
||||
<span class="keyword">return</span> <span class="identifier">r</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<pre class="programlisting"><span class="identifier">show_cube_root</span><span class="special">(</span><span class="number">2.</span><span class="special">);</span>
|
||||
<span class="identifier">show_cube_root</span><span class="special">(</span><span class="number">2.L</span><span class="special">);</span>
|
||||
<span class="identifier">show_cube_root</span><span class="special">(</span><span class="identifier">two</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
which outputs:
|
||||
</p>
|
||||
<pre class="programlisting">cbrt(2) = 1.2599210498948731647672106072782283505702514647015
|
||||
|
||||
value = 2, cube root =1.25992104989487
|
||||
value = 2, cube root =1.25992104989487
|
||||
value = 2, cube root =1.2599210498948731647672106072782283505702514647015
|
||||
</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>
|
||||
Be <span class="bold"><strong>very careful</strong></span> about the floating-point
|
||||
type <code class="computeroutput"><span class="identifier">T</span></code> that is passed
|
||||
to the root-finding function. Carelessly passing a integer by writing
|
||||
<code class="computeroutput"><span class="identifier">cpp_dec_float_50</span> <span class="identifier">r</span>
|
||||
<span class="special">=</span> <span class="identifier">cbrt_2deriv</span><span class="special">(</span><span class="number">2</span><span class="special">);</span></code>
|
||||
or <code class="computeroutput"><span class="identifier">show_cube_root</span><span class="special">(</span><span class="number">2</span><span class="special">);</span></code> will
|
||||
provoke many warnings and compile errors.
|
||||
</p>
|
||||
<p>
|
||||
Even <code class="computeroutput"><span class="identifier">show_cube_root</span><span class="special">(</span><span class="number">2.F</span><span class="special">);</span></code> will
|
||||
produce warnings because <code class="computeroutput"><span class="keyword">typedef</span>
|
||||
<span class="keyword">double</span> <span class="identifier">guess_type</span></code>
|
||||
defines the type used to compute the guess and bracket values as <code class="computeroutput"><span class="keyword">double</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
Even more treacherous is passing a <code class="computeroutput"><span class="keyword">double</span></code>
|
||||
as in <code class="computeroutput"><span class="identifier">cpp_dec_float_50</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">cbrt_2deriv</span><span class="special">(</span><span class="number">2.</span><span class="special">);</span></code> which
|
||||
silently gives the 'wrong' result, computing a <code class="computeroutput"><span class="keyword">double</span></code>
|
||||
result and <span class="bold"><strong>then</strong></span> converting to <code class="computeroutput"><span class="identifier">cpp_dec_float_50</span></code>! All digits beyond
|
||||
<code class="computeroutput"><span class="identifier">max_digits10</span></code> will be
|
||||
incorrect. Making the <code class="computeroutput"><span class="identifier">cbrt</span></code>
|
||||
type explicit with <code class="computeroutput"><span class="identifier">cbrt_2deriv</span><span class="special"><</span><span class="identifier">cpp_dec_float_50</span><span class="special">>(</span><span class="number">2.</span><span class="special">);</span></code> will give you the desired 50 decimal
|
||||
digit precision result.
|
||||
</p>
|
||||
</td></tr>
|
||||
</table></div>
|
||||
<p>
|
||||
Full code of this example is at <a href="../../../../../example/root_finding_multiprecision_example.cpp" target="_top">root_finding_multiprecision_example.cpp</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 © 2006-2010, 2012-2014 Nikhar Agrawal,
|
||||
Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
|
||||
Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan Råde, Gautam Sewani,
|
||||
Benjamin Sobotta, 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="5th_root_eg.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../root_finding_examples.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="nth_root.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,184 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Generalizing to Compute the nth root</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.5.1">
|
||||
<link rel="up" href="../root_finding_examples.html" title="Examples of Root-Finding (with and without derivatives)">
|
||||
<link rel="prev" href="multiprecision_root.html" title="Root-finding using Boost.Multiprecision">
|
||||
<link rel="next" href="elliptic_eg.html" title="A More complex example - Inverting the Elliptic Integrals">
|
||||
</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="multiprecision_root.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../root_finding_examples.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="elliptic_eg.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="math_toolkit.roots.root_finding_examples.nth_root"></a><a class="link" href="nth_root.html" title="Generalizing to Compute the nth root">Generalizing
|
||||
to Compute the nth root</a>
|
||||
</h4></div></div></div>
|
||||
<p>
|
||||
If desired, we can now further generalize to compute the <span class="emphasis"><em>n</em></span>th
|
||||
root by computing the derivatives <span class="bold"><strong>at compile-time</strong></span>
|
||||
using the rules for differentiation and <code class="computeroutput"><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"><</span><span class="identifier">N</span><span class="special">></span></code> where template parameter <code class="computeroutput"><span class="identifier">N</span></code> is an integer and a compile time constant.
|
||||
Our functor and function now have an additional template parameter <code class="computeroutput"><span class="identifier">N</span></code>, for the root required.
|
||||
</p>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td align="left" valign="top"><p>
|
||||
Since the powers and derivatives are fixed at compile time, the resulting
|
||||
code is as efficient as as if hand-coded as the cube and fifth-root examples
|
||||
above. A good compiler should also optimise any repeated multiplications.
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
<p>
|
||||
Our <span class="emphasis"><em>n</em></span>th root functor is
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">int</span> <span class="identifier">N</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span> <span class="special">=</span> <span class="keyword">double</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">nth_functor_2deriv</span>
|
||||
<span class="special">{</span> <span class="comment">// Functor returning both 1st and 2nd derivatives.</span>
|
||||
<span class="identifier">BOOST_STATIC_ASSERT_MSG</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_integral</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value</span> <span class="special">==</span> <span class="keyword">false</span><span class="special">,</span> <span class="string">"Only floating-point type types can be used!"</span><span class="special">);</span>
|
||||
<span class="identifier">BOOST_STATIC_ASSERT_MSG</span><span class="special">((</span><span class="identifier">N</span> <span class="special">></span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="keyword">true</span><span class="special">,</span> <span class="string">"root N must be > 0!"</span><span class="special">);</span>
|
||||
|
||||
<span class="identifier">nth_functor_2deriv</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">to_find_root_of</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">a</span><span class="special">(</span><span class="identifier">to_find_root_of</span><span class="special">)</span>
|
||||
<span class="special">{</span> <span class="comment">/* Constructor stores value a to find root of, for example: */</span> <span class="special">}</span>
|
||||
|
||||
<span class="comment">// using boost::math::tuple; // to return three values.</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">x</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// Return f(x), f'(x) and f''(x).</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">pow</span><span class="special">;</span>
|
||||
<span class="identifier">T</span> <span class="identifier">fx</span> <span class="special">=</span> <span class="identifier">pow</span><span class="special"><</span><span class="identifier">N</span><span class="special">>(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">-</span> <span class="identifier">a</span><span class="special">;</span> <span class="comment">// Difference (estimate x^n - a).</span>
|
||||
<span class="identifier">T</span> <span class="identifier">dx</span> <span class="special">=</span> <span class="identifier">N</span> <span class="special">*</span> <span class="identifier">pow</span><span class="special"><</span><span class="identifier">N</span> <span class="special">-</span> <span class="number">1</span><span class="special">>(</span><span class="identifier">x</span><span class="special">);</span> <span class="comment">// 1st derivative f'(x).</span>
|
||||
<span class="identifier">T</span> <span class="identifier">d2x</span> <span class="special">=</span> <span class="identifier">N</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">N</span> <span class="special">-</span> <span class="number">1</span><span class="special">)</span> <span class="special">*</span> <span class="identifier">pow</span><span class="special"><</span><span class="identifier">N</span> <span class="special">-</span> <span class="number">2</span> <span class="special">>(</span><span class="identifier">x</span><span class="special">);</span> <span class="comment">// 2nd derivative f''(x).</span>
|
||||
|
||||
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">fx</span><span class="special">,</span> <span class="identifier">dx</span><span class="special">,</span> <span class="identifier">d2x</span><span class="special">);</span> <span class="comment">// 'return' fx, dx and d2x.</span>
|
||||
<span class="special">}</span>
|
||||
<span class="keyword">private</span><span class="special">:</span>
|
||||
<span class="identifier">T</span> <span class="identifier">a</span><span class="special">;</span> <span class="comment">// to be 'nth_rooted'.</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
and our <span class="emphasis"><em>n</em></span>th root function is
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">int</span> <span class="identifier">N</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span> <span class="special">=</span> <span class="keyword">double</span><span class="special">></span>
|
||||
<span class="identifier">T</span> <span class="identifier">nth_2deriv</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">x</span><span class="special">)</span>
|
||||
<span class="special">{</span> <span class="comment">// return nth root of x using 1st and 2nd derivatives and Halley.</span>
|
||||
|
||||
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">std</span><span class="special">;</span> <span class="comment">// Help ADL of std functions.</span>
|
||||
<span class="keyword">using</span> <span class="keyword">namespace</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="comment">// For halley_iterate.</span>
|
||||
|
||||
<span class="identifier">BOOST_STATIC_ASSERT_MSG</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_integral</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value</span> <span class="special">==</span> <span class="keyword">false</span><span class="special">,</span> <span class="string">"Only floating-point type types can be used!"</span><span class="special">);</span>
|
||||
<span class="identifier">BOOST_STATIC_ASSERT_MSG</span><span class="special">((</span><span class="identifier">N</span> <span class="special">></span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="keyword">true</span><span class="special">,</span> <span class="string">"root N must be > 0!"</span><span class="special">);</span>
|
||||
<span class="identifier">BOOST_STATIC_ASSERT_MSG</span><span class="special">((</span><span class="identifier">N</span> <span class="special">></span> <span class="number">1000</span><span class="special">)</span> <span class="special">==</span> <span class="keyword">false</span><span class="special">,</span> <span class="string">"root N is too big!"</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">typedef</span> <span class="keyword">double</span> <span class="identifier">guess_type</span><span class="special">;</span> <span class="comment">// double may restrict (exponent) range for a multiprecision T?</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">exponent</span><span class="special">;</span>
|
||||
<span class="identifier">frexp</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">guess_type</span><span class="special">>(</span><span class="identifier">x</span><span class="special">),</span> <span class="special">&</span><span class="identifier">exponent</span><span class="special">);</span> <span class="comment">// Get exponent of z (ignore mantissa).</span>
|
||||
<span class="identifier">T</span> <span class="identifier">guess</span> <span class="special">=</span> <span class="identifier">ldexp</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">guess_type</span><span class="special">>(</span><span class="number">1.</span><span class="special">),</span> <span class="identifier">exponent</span> <span class="special">/</span> <span class="identifier">N</span><span class="special">);</span> <span class="comment">// Rough guess is to divide the exponent by n.</span>
|
||||
<span class="identifier">T</span> <span class="identifier">min</span> <span class="special">=</span> <span class="identifier">ldexp</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">guess_type</span><span class="special">>(</span><span class="number">1.</span><span class="special">)</span> <span class="special">/</span> <span class="number">2</span><span class="special">,</span> <span class="identifier">exponent</span> <span class="special">/</span> <span class="identifier">N</span><span class="special">);</span> <span class="comment">// Minimum possible value is half our guess.</span>
|
||||
<span class="identifier">T</span> <span class="identifier">max</span> <span class="special">=</span> <span class="identifier">ldexp</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">guess_type</span><span class="special">>(</span><span class="number">2.</span><span class="special">),</span> <span class="identifier">exponent</span> <span class="special">/</span> <span class="identifier">N</span><span class="special">);</span> <span class="comment">// Maximum possible value is twice our guess.</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">digits</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">digits</span> <span class="special">*</span> <span class="number">0.4</span><span class="special">;</span> <span class="comment">// Accuracy triples with each step, so stop when</span>
|
||||
<span class="comment">// slightly more than one third of the digits are correct.</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">T</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">halley_iterate</span><span class="special">(</span><span class="identifier">nth_functor_2deriv</span><span class="special"><</span><span class="identifier">N</span><span class="special">,</span> <span class="identifier">T</span><span class="special">>(</span><span class="identifier">x</span><span class="special">),</span> <span class="identifier">guess</span><span class="special">,</span> <span class="identifier">min</span><span class="special">,</span> <span class="identifier">max</span><span class="special">,</span> <span class="identifier">digits</span><span class="special">,</span> <span class="identifier">it</span><span class="special">);</span>
|
||||
<span class="keyword">return</span> <span class="identifier">result</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<pre class="programlisting"> <span class="identifier">show_nth_root</span><span class="special"><</span><span class="number">5</span><span class="special">,</span> <span class="keyword">double</span><span class="special">>(</span><span class="number">2.</span><span class="special">);</span>
|
||||
<span class="identifier">show_nth_root</span><span class="special"><</span><span class="number">5</span><span class="special">,</span> <span class="keyword">long</span> <span class="keyword">double</span><span class="special">>(</span><span class="number">2.</span><span class="special">);</span>
|
||||
<span class="preprocessor">#ifndef</span> <span class="identifier">_MSC_VER</span> <span class="comment">// float128 is not supported by Microsoft compiler 2013.</span>
|
||||
<span class="identifier">show_nth_root</span><span class="special"><</span><span class="number">5</span><span class="special">,</span> <span class="identifier">float128</span><span class="special">>(</span><span class="number">2</span><span class="special">);</span>
|
||||
<span class="preprocessor">#endif</span>
|
||||
<span class="identifier">show_nth_root</span><span class="special"><</span><span class="number">5</span><span class="special">,</span> <span class="identifier">cpp_dec_float_50</span><span class="special">>(</span><span class="number">2</span><span class="special">);</span> <span class="comment">// dec</span>
|
||||
<span class="identifier">show_nth_root</span><span class="special"><</span><span class="number">5</span><span class="special">,</span> <span class="identifier">cpp_bin_float_50</span><span class="special">>(</span><span class="number">2</span><span class="special">);</span> <span class="comment">// bin</span>
|
||||
</pre>
|
||||
<p>
|
||||
produces an output similar to this
|
||||
</p>
|
||||
<pre class="programlisting"> <span class="identifier">Using</span> <span class="identifier">MSVC</span> <span class="number">2013</span>
|
||||
|
||||
<span class="identifier">nth</span> <span class="identifier">Root</span> <span class="identifier">finding</span> <span class="identifier">Example</span><span class="special">.</span>
|
||||
<span class="identifier">Type</span> <span class="keyword">double</span> <span class="identifier">value</span> <span class="special">=</span> <span class="number">2</span><span class="special">,</span> <span class="number">5</span><span class="identifier">th</span> <span class="identifier">root</span> <span class="special">=</span> <span class="number">1.14869835499704</span>
|
||||
<span class="identifier">Type</span> <span class="keyword">long</span> <span class="keyword">double</span> <span class="identifier">value</span> <span class="special">=</span> <span class="number">2</span><span class="special">,</span> <span class="number">5</span><span class="identifier">th</span> <span class="identifier">root</span> <span class="special">=</span> <span class="number">1.14869835499704</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"><</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_dec_float</span><span class="special"><</span><span class="number">50</span><span class="special">,</span><span class="keyword">int</span><span class="special">,</span><span class="keyword">void</span><span class="special">>,</span><span class="number">1</span><span class="special">></span> <span class="identifier">value</span> <span class="special">=</span> <span class="number">2</span><span class="special">,</span>
|
||||
<span class="number">5</span><span class="identifier">th</span> <span class="identifier">root</span> <span class="special">=</span> <span class="number">1.1486983549970350067986269467779275894438508890978</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"><</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"><</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">>,</span><span class="number">0</span><span class="special">></span> <span class="identifier">value</span> <span class="special">=</span> <span class="number">2</span><span class="special">,</span>
|
||||
<span class="number">5</span><span class="identifier">th</span> <span class="identifier">root</span> <span class="special">=</span> <span class="number">1.1486983549970350067986269467779275894438508890978</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>
|
||||
Take care with the type passed to the function. It is best to pass a
|
||||
<code class="computeroutput"><span class="keyword">double</span></code> or greater-precision
|
||||
floating-point type.
|
||||
</p>
|
||||
<p>
|
||||
Passing an integer value, for example, <code class="computeroutput"><span class="identifier">nth_2deriv</span><span class="special"><</span><span class="number">5</span><span class="special">>(</span><span class="number">2</span><span class="special">)</span></code> will
|
||||
be rejected, while <code class="computeroutput"><span class="identifier">nth_2deriv</span><span class="special"><</span><span class="number">5</span><span class="special">,</span>
|
||||
<span class="keyword">double</span><span class="special">>(</span><span class="number">2</span><span class="special">)</span></code> converts
|
||||
the integer to <code class="computeroutput"><span class="keyword">double</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
Avoid passing a <code class="computeroutput"><span class="keyword">float</span></code> value
|
||||
that will provoke warnings (actually spurious) from the compiler about
|
||||
potential loss of data, as noted above.
|
||||
</p>
|
||||
</td></tr>
|
||||
</table></div>
|
||||
<div class="warning"><table border="0" summary="Warning">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../../../doc/src/images/warning.png"></td>
|
||||
<th align="left">Warning</th>
|
||||
</tr>
|
||||
<tr><td align="left" valign="top"><p>
|
||||
Asking for unreasonable roots, for example, <code class="computeroutput"><span class="identifier">show_nth_root</span><span class="special"><</span><span class="number">1000000</span><span class="special">>(</span><span class="number">2.</span><span class="special">);</span></code> may lead to <a href="http://en.wikipedia.org/wiki/Loss_of_significance" target="_top">Loss
|
||||
of significance</a> like <code class="computeroutput"><span class="identifier">Type</span>
|
||||
<span class="keyword">double</span> <span class="identifier">value</span>
|
||||
<span class="special">=</span> <span class="number">2</span><span class="special">,</span> <span class="number">1000000</span><span class="identifier">th</span> <span class="identifier">root</span>
|
||||
<span class="special">=</span> <span class="number">1.00000069314783</span></code>.
|
||||
Use of the the <code class="computeroutput"><span class="identifier">pow</span></code> function
|
||||
is more sensible for this unusual need.
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
<p>
|
||||
Full code of this example is at <a href="../../../../../example/root_finding_n_example.cpp" target="_top">root_finding_n_example.cpp</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 © 2006-2010, 2012-2014 Nikhar Agrawal,
|
||||
Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
|
||||
Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan Råde, Gautam Sewani,
|
||||
Benjamin Sobotta, 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="multiprecision_root.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../root_finding_examples.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="elliptic_eg.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,315 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Root Finding With Derivatives: Newton-Raphson, Halley & Schrö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.5.1">
|
||||
<link rel="up" href="../roots.html" title="Root finding">
|
||||
<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="../roots.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><h3 class="title">
|
||||
<a name="math_toolkit.roots.roots_deriv"></a><a class="link" href="roots_deriv.html" title="Root Finding With Derivatives: Newton-Raphson, Halley & Schröder">Root Finding With Derivatives:
|
||||
Newton-Raphson, Halley & Schröder</a>
|
||||
</h3></div></div></div>
|
||||
<h5>
|
||||
<a name="math_toolkit.roots.roots_deriv.h0"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.roots_deriv.synopsis"></a></span><a class="link" href="roots_deriv.html#math_toolkit.roots.roots_deriv.synopsis">Synopsis</a>
|
||||
</h5>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">tools</span><span class="special">/</span><span class="identifier">roots</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></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"><</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">></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"><</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">></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">&</span> <span class="identifier">max_iter</span><span class="special">);</span>
|
||||
|
||||
<span class="comment">// Halley</span>
|
||||
<span class="keyword">template</span> <span class="special"><</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">></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"><</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">></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">&</span> <span class="identifier">max_iter</span><span class="special">);</span>
|
||||
|
||||
<span class="comment">// Schr'''&#xf6;'''der</span>
|
||||
<span class="keyword">template</span> <span class="special"><</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">></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"><</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">></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">&</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.roots_deriv.h1"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.roots_deriv.description"></a></span><a class="link" href="roots_deriv.html#math_toolkit.roots.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.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.roots_deriv.halley">Halley</a> and
|
||||
<a class="link" href="roots_deriv.html#math_toolkit.roots.roots_deriv.schroder">Schrö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ö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& 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"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">>::</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"><</span><span class="identifier">T</span><span class="special">>::</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ö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"><</span><span class="identifier">T</span><span class="special">>::</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"><</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">></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"><</span><span class="keyword">double</span><span class="special">>::</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"><</span><span class="keyword">double</span><span class="special">>::</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.roots_deriv.h2"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.roots_deriv.newton"></a></span><a class="link" href="roots_deriv.html#math_toolkit.roots.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.roots_deriv.h3"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.roots_deriv.halley"></a></span><a class="link" href="roots_deriv.html#math_toolkit.roots.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.roots_deriv.h4"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.roots_deriv.schroder"></a></span><a class="link" href="roots_deriv.html#math_toolkit.roots.roots_deriv.schroder">Schrö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ö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ö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.roots_deriv.h5"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.roots_deriv.examples"></a></span><a class="link" href="roots_deriv.html#math_toolkit.roots.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 © 2006-2010, 2012-2014 Nikhar Agrawal,
|
||||
Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
|
||||
Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan Råde, Gautam Sewani,
|
||||
Benjamin Sobotta, 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="../roots.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>
|
||||
@@ -0,0 +1,222 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Root Finding Without Derivatives</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.5.1">
|
||||
<link rel="up" href="../roots.html" title="Root finding">
|
||||
<link rel="prev" href="../roots.html" title="Root finding">
|
||||
<link rel="next" href="roots_noderiv/bisect.html" title="Bisection">
|
||||
</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.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots.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="roots_noderiv/bisect.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="math_toolkit.roots.roots_noderiv"></a><a class="link" href="roots_noderiv.html" title="Root Finding Without Derivatives">Root Finding Without
|
||||
Derivatives</a>
|
||||
</h3></div></div></div>
|
||||
<div class="toc"><dl class="toc">
|
||||
<dt><span class="section"><a href="roots_noderiv/bisect.html">Bisection</a></span></dt>
|
||||
<dt><span class="section"><a href="roots_noderiv/bracket_solve.html">Bracket
|
||||
and Solve Root</a></span></dt>
|
||||
<dt><span class="section"><a href="roots_noderiv/TOMS748.html">Algorithm
|
||||
TOMS 748: Alefeld, Potra and Shi: Enclosing zeros of continuous functions</a></span></dt>
|
||||
<dt><span class="section"><a href="roots_noderiv/brent.html">Brent-Decker
|
||||
Algorithm</a></span></dt>
|
||||
<dt><span class="section"><a href="roots_noderiv/root_termination.html">Termination
|
||||
Condition Functors</a></span></dt>
|
||||
<dt><span class="section"><a href="roots_noderiv/implementation.html">Implementation</a></span></dt>
|
||||
</dl></div>
|
||||
<h5>
|
||||
<a name="math_toolkit.roots.roots_noderiv.h0"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.roots_noderiv.synopsis"></a></span><a class="link" href="roots_noderiv.html#math_toolkit.roots.roots_noderiv.synopsis">Synopsis</a>
|
||||
</h5>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">tools</span><span class="special">/</span><span class="identifier">roots</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></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">// Bisection</span>
|
||||
<span class="keyword">template</span> <span class="special"><</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">,</span> <span class="keyword">class</span> <span class="identifier">Tol</span><span class="special">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">bisect</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="identifier">Tol</span> <span class="identifier">tol</span><span class="special">,</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&</span> <span class="identifier">max_iter</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</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">,</span> <span class="keyword">class</span> <span class="identifier">Tol</span><span class="special">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">bisect</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="identifier">Tol</span> <span class="identifier">tol</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</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">,</span> <span class="keyword">class</span> <span class="identifier">Tol</span><span class="special">,</span> <span class="keyword">class</span> <a class="link" href="../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">bisect</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="identifier">Tol</span> <span class="identifier">tol</span><span class="special">,</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&</span> <span class="identifier">max_iter</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <a class="link" href="../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&);</span>
|
||||
|
||||
<span class="comment">// Bracket and Solve Root</span>
|
||||
<span class="keyword">template</span> <span class="special"><</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">,</span> <span class="keyword">class</span> <span class="identifier">Tol</span><span class="special">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">bracket_and_solve_root</span><span class="special">(</span>
|
||||
<span class="identifier">F</span> <span class="identifier">f</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">guess</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">factor</span><span class="special">,</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">rising</span><span class="special">,</span>
|
||||
<span class="identifier">Tol</span> <span class="identifier">tol</span><span class="special">,</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&</span> <span class="identifier">max_iter</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</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">,</span> <span class="keyword">class</span> <span class="identifier">Tol</span><span class="special">,</span> <span class="keyword">class</span> <a class="link" href="../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">bracket_and_solve_root</span><span class="special">(</span>
|
||||
<span class="identifier">F</span> <span class="identifier">f</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">guess</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">factor</span><span class="special">,</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">rising</span><span class="special">,</span>
|
||||
<span class="identifier">Tol</span> <span class="identifier">tol</span><span class="special">,</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&</span> <span class="identifier">max_iter</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <a class="link" href="../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&);</span>
|
||||
|
||||
<span class="comment">// TOMS 748 algorithm</span>
|
||||
<span class="keyword">template</span> <span class="special"><</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">,</span> <span class="keyword">class</span> <span class="identifier">Tol</span><span class="special">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">toms748_solve</span><span class="special">(</span>
|
||||
<span class="identifier">F</span> <span class="identifier">f</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">a</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">b</span><span class="special">,</span>
|
||||
<span class="identifier">Tol</span> <span class="identifier">tol</span><span class="special">,</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&</span> <span class="identifier">max_iter</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</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">,</span> <span class="keyword">class</span> <span class="identifier">Tol</span><span class="special">,</span> <span class="keyword">class</span> <a class="link" href="../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">toms748_solve</span><span class="special">(</span>
|
||||
<span class="identifier">F</span> <span class="identifier">f</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">a</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">b</span><span class="special">,</span>
|
||||
<span class="identifier">Tol</span> <span class="identifier">tol</span><span class="special">,</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&</span> <span class="identifier">max_iter</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <a class="link" href="../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</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">,</span> <span class="keyword">class</span> <span class="identifier">Tol</span><span class="special">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">toms748_solve</span><span class="special">(</span>
|
||||
<span class="identifier">F</span> <span class="identifier">f</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">a</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">b</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">fa</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">fb</span><span class="special">,</span>
|
||||
<span class="identifier">Tol</span> <span class="identifier">tol</span><span class="special">,</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&</span> <span class="identifier">max_iter</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</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">,</span> <span class="keyword">class</span> <span class="identifier">Tol</span><span class="special">,</span> <span class="keyword">class</span> <a class="link" href="../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">toms748_solve</span><span class="special">(</span>
|
||||
<span class="identifier">F</span> <span class="identifier">f</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">a</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">b</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">fa</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">fb</span><span class="special">,</span>
|
||||
<span class="identifier">Tol</span> <span class="identifier">tol</span><span class="special">,</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&</span> <span class="identifier">max_iter</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <a class="link" href="../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&);</span>
|
||||
|
||||
<span class="comment">// Termination conditions:</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">eps_tolerance</span><span class="special">;</span>
|
||||
|
||||
<span class="keyword">struct</span> <span class="identifier">equal_floor</span><span class="special">;</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">equal_ceil</span><span class="special">;</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">equal_nearest_integer</span><span class="special">;</span>
|
||||
|
||||
<span class="special">}}}</span> <span class="comment">// boost::math::tools namespaces</span>
|
||||
</pre>
|
||||
<h5>
|
||||
<a name="math_toolkit.roots.roots_noderiv.h1"></a>
|
||||
<span class="phrase"><a name="math_toolkit.roots.roots_noderiv.description"></a></span><a class="link" href="roots_noderiv.html#math_toolkit.roots.roots_noderiv.description">Description</a>
|
||||
</h5>
|
||||
<p>
|
||||
These functions solve the root of some function <span class="emphasis"><em>f(x)</em></span>
|
||||
- <span class="emphasis"><em>without the need for any derivatives of <span class="emphasis"><em>f(x)</em></span></em></span>.
|
||||
</p>
|
||||
<p>
|
||||
The <code class="computeroutput"><span class="identifier">bracket_and_solve_root</span></code>
|
||||
functions use <a class="link" href="roots_noderiv/TOMS748.html" title="Algorithm TOMS 748: Alefeld, Potra and Shi: Enclosing zeros of continuous functions">TOMS
|
||||
748 algorithm</a> by Alefeld, Potra and Shi that is asymptotically the
|
||||
most efficient known, and has been shown to be optimal for a certain classes
|
||||
of smooth functions. Variants with and without <a class="link" href="../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">Policies</a>
|
||||
are provided.
|
||||
</p>
|
||||
<p>
|
||||
Alternatively, <a class="link" href="roots_noderiv/bisect.html" title="Bisection">bisect</a>
|
||||
is a simple <a href="https://en.wikipedia.org/wiki/Bisection" target="_top">bisection</a>
|
||||
routine which can be useful in its own right in some situations, or alternatively
|
||||
for narrowing down the range containing the root, prior to calling a more
|
||||
advanced algorithm.
|
||||
</p>
|
||||
<p>
|
||||
All the algorithms in this section reduce the diameter of the enclosing interval
|
||||
with the same asymptotic efficiency with which they locate the root. This
|
||||
is in contrast to the derivative based methods which may <span class="emphasis"><em>never</em></span>
|
||||
significantly reduce the enclosing interval, even though they rapidly approach
|
||||
the root. This is also in contrast to some other derivative-free methods
|
||||
(for example, Brent's method described at <a href="http://en.wikipedia.org/wiki/Brent%27s_method" target="_top">Brent-Dekker)</a>
|
||||
which only reduces the enclosing interval on the final step. Therefore these
|
||||
methods return a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span></code> containing the enclosing interval
|
||||
found, and accept a function object specifying the termination condition.
|
||||
</p>
|
||||
<p>
|
||||
Three function objects are provided for ready-made termination conditions:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<span class="emphasis"><em>eps_tolerance</em></span> causes termination when the relative
|
||||
error in the enclosing interval is below a certain threshold.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="emphasis"><em>equal_floor</em></span> and <span class="emphasis"><em>equal_ceil</em></span>
|
||||
are useful for certain statistical applications where the result is known
|
||||
to be an integer.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Other user-defined termination conditions are likely to be used only
|
||||
rarely, but may be useful in some specific circumstances.
|
||||
</li>
|
||||
</ul></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 © 2006-2010, 2012-2014 Nikhar Agrawal,
|
||||
Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
|
||||
Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan Råde, Gautam Sewani,
|
||||
Benjamin Sobotta, 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.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots.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="roots_noderiv/bisect.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,193 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Algorithm TOMS 748: Alefeld, Potra and Shi: Enclosing zeros of continuous functions</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.5.1">
|
||||
<link rel="up" href="../roots_noderiv.html" title="Root Finding Without Derivatives">
|
||||
<link rel="prev" href="bracket_solve.html" title="Bracket and Solve Root">
|
||||
<link rel="next" href="brent.html" title="Brent-Decker Algorithm">
|
||||
</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="bracket_solve.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots_noderiv.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="brent.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="math_toolkit.roots.roots_noderiv.TOMS748"></a><a class="link" href="TOMS748.html" title="Algorithm TOMS 748: Alefeld, Potra and Shi: Enclosing zeros of continuous functions">Algorithm
|
||||
TOMS 748: Alefeld, Potra and Shi: Enclosing zeros of continuous functions</a>
|
||||
</h4></div></div></div>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</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">,</span> <span class="keyword">class</span> <span class="identifier">Tol</span><span class="special">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">toms748_solve</span><span class="special">(</span>
|
||||
<span class="identifier">F</span> <span class="identifier">f</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">a</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">b</span><span class="special">,</span>
|
||||
<span class="identifier">Tol</span> <span class="identifier">tol</span><span class="special">,</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&</span> <span class="identifier">max_iter</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</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">,</span> <span class="keyword">class</span> <span class="identifier">Tol</span><span class="special">,</span> <span class="keyword">class</span> <a class="link" href="../../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">toms748_solve</span><span class="special">(</span>
|
||||
<span class="identifier">F</span> <span class="identifier">f</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">a</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">b</span><span class="special">,</span>
|
||||
<span class="identifier">Tol</span> <span class="identifier">tol</span><span class="special">,</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&</span> <span class="identifier">max_iter</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <a class="link" href="../../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</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">,</span> <span class="keyword">class</span> <span class="identifier">Tol</span><span class="special">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">toms748_solve</span><span class="special">(</span>
|
||||
<span class="identifier">F</span> <span class="identifier">f</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">a</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">b</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">fa</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">fb</span><span class="special">,</span>
|
||||
<span class="identifier">Tol</span> <span class="identifier">tol</span><span class="special">,</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&</span> <span class="identifier">max_iter</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</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">,</span> <span class="keyword">class</span> <span class="identifier">Tol</span><span class="special">,</span> <span class="keyword">class</span> <a class="link" href="../../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">toms748_solve</span><span class="special">(</span>
|
||||
<span class="identifier">F</span> <span class="identifier">f</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">a</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">b</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">fa</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">fb</span><span class="special">,</span>
|
||||
<span class="identifier">Tol</span> <span class="identifier">tol</span><span class="special">,</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&</span> <span class="identifier">max_iter</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <a class="link" href="../../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&);</span>
|
||||
</pre>
|
||||
<p>
|
||||
These functions implement TOMS Algorithm 748: it uses a mixture of cubic,
|
||||
quadratic and linear (secant) interpolation to locate the root of <span class="emphasis"><em>f(x)</em></span>.
|
||||
The two pairs of functions differ only by whether values for <span class="emphasis"><em>f(a)</em></span>
|
||||
and <span class="emphasis"><em>f(b)</em></span> are already available.
|
||||
</p>
|
||||
<p>
|
||||
Generally speaking it is easier (and often more efficient) to use <a class="link" href="bracket_solve.html" title="Bracket and Solve Root">bracket and solve</a>
|
||||
rather than trying to bracket the root yourself as this function requires.
|
||||
</p>
|
||||
<p>
|
||||
This function is provided rather than <a href="http://en.wikipedia.org/wiki/Brent%27s_method" target="_top">Brent's
|
||||
method</a> as it is known to be more effient in many cases (it is asymptotically
|
||||
the most efficient known, and has been shown to be optimal for a certain
|
||||
classes of smooth functions). It also has the useful property of decreasing
|
||||
the bracket size with each step, unlike Brent's method which only shrinks
|
||||
the enclosing interval in the final step. This makes it particularly useful
|
||||
when you need a result where the ends of the interval round to the same
|
||||
integer: as often happens in statistical applications for example. In this
|
||||
situation the function is able to exit after a much smaller number of iterations
|
||||
than would otherwise be possible.
|
||||
</p>
|
||||
<p>
|
||||
The <a class="link" href="TOMS748.html" title="Algorithm TOMS 748: Alefeld, Potra and Shi: Enclosing zeros of continuous functions">TOMS 748 algorithm</a>
|
||||
parameters are:
|
||||
</p>
|
||||
<div class="variablelist">
|
||||
<p class="title"><b></b></p>
|
||||
<dl class="variablelist">
|
||||
<dt><span class="term">f</span></dt>
|
||||
<dd><p>
|
||||
A unary functor that is the function whose root is to be solved.
|
||||
f(x) need not be uniformly increasing or decreasing on <span class="emphasis"><em>x</em></span>
|
||||
and may have multiple roots. However, the bounds given must bracket
|
||||
a single root.
|
||||
</p></dd>
|
||||
<dt><span class="term">a</span></dt>
|
||||
<dd><p>
|
||||
The lower bound for the initial bracket of the root.
|
||||
</p></dd>
|
||||
<dt><span class="term">b</span></dt>
|
||||
<dd><p>
|
||||
The upper bound for the initial bracket of the root. It is a precondition
|
||||
that <span class="emphasis"><em>a < b</em></span> and that <span class="emphasis"><em>a</em></span>
|
||||
and <span class="emphasis"><em>b</em></span> bracket the root to find so that <span class="emphasis"><em>f(a)
|
||||
* f(b) < 0</em></span>.
|
||||
</p></dd>
|
||||
<dt><span class="term">fa</span></dt>
|
||||
<dd><p>
|
||||
Optional: the value of <span class="emphasis"><em>f(a)</em></span>.
|
||||
</p></dd>
|
||||
<dt><span class="term">fb</span></dt>
|
||||
<dd><p>
|
||||
Optional: the value of <span class="emphasis"><em>f(b)</em></span>.
|
||||
</p></dd>
|
||||
<dt><span class="term">tol</span></dt>
|
||||
<dd><p>
|
||||
A binary functor that determines the termination condition for the
|
||||
search for the root. <span class="emphasis"><em>tol</em></span> is passed the current
|
||||
brackets at each step, when it returns true, then the current brackets
|
||||
are returned as the result. See also <a class="link" href="root_termination.html" title="Termination Condition Functors">predefined
|
||||
termination functors</a>.
|
||||
</p></dd>
|
||||
<dt><span class="term">max_iter</span></dt>
|
||||
<dd><p>
|
||||
The maximum number of function invocations to perform in the search
|
||||
for the root. On exit, <span class="emphasis"><em>max_iter</em></span> is set to actual
|
||||
number of function invocations used.
|
||||
</p></dd>
|
||||
</dl>
|
||||
</div>
|
||||
<p>
|
||||
The final <a class="link" href="../../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">Policy</a> argument is optional and
|
||||
can be used to control the behaviour of the function: how it handles errors,
|
||||
what level of precision to use etc. Refer to the <a class="link" href="../../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">policy
|
||||
documentation for more details</a>.
|
||||
</p>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">toms748_solve</span></code> returns:
|
||||
a pair of values <span class="emphasis"><em>r</em></span> that bracket the root so that:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">f</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="special">*</span> <span class="identifier">f</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="special"><=</span> <span class="number">0</span>
|
||||
</pre>
|
||||
<p>
|
||||
and either
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">tol</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">r</span><span class="special">.</span><span class="identifier">second</span><span class="special">)</span> <span class="special">==</span> <span class="keyword">true</span>
|
||||
</pre>
|
||||
<p>
|
||||
or
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">max_iter</span> <span class="special">>=</span> <span class="identifier">m</span>
|
||||
</pre>
|
||||
<p>
|
||||
where <span class="emphasis"><em>m</em></span> is the initial value of <span class="emphasis"><em>max_iter</em></span>
|
||||
passed to the function.
|
||||
</p>
|
||||
<p>
|
||||
In other words, it's up to the caller to verify whether termination occurred
|
||||
as a result of exceeding <span class="emphasis"><em>max_iter</em></span> function invocations
|
||||
(easily done by checking the updated value of <span class="emphasis"><em>max_iter</em></span>
|
||||
against its previous value passed as parameter), rather than because the
|
||||
termination condition <span class="emphasis"><em>tol</em></span> was satisfied.
|
||||
</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 © 2006-2010, 2012-2014 Nikhar Agrawal,
|
||||
Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
|
||||
Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan Råde, Gautam Sewani,
|
||||
Benjamin Sobotta, 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="bracket_solve.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots_noderiv.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="brent.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,152 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Bisection</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.5.1">
|
||||
<link rel="up" href="../roots_noderiv.html" title="Root Finding Without Derivatives">
|
||||
<link rel="prev" href="../roots_noderiv.html" title="Root Finding Without Derivatives">
|
||||
<link rel="next" href="bracket_solve.html" title="Bracket and Solve Root">
|
||||
</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.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots_noderiv.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="bracket_solve.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="math_toolkit.roots.roots_noderiv.bisect"></a><a class="link" href="bisect.html" title="Bisection">Bisection</a>
|
||||
</h4></div></div></div>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</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">,</span> <span class="keyword">class</span> <span class="identifier">Tol</span><span class="special">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">bisect</span><span class="special">(</span> <span class="comment">// Unlimited iterations.</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="identifier">Tol</span> <span class="identifier">tol</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</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">,</span> <span class="keyword">class</span> <span class="identifier">Tol</span><span class="special">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">bisect</span><span class="special">(</span> <span class="comment">// Limited iterations.</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="identifier">Tol</span> <span class="identifier">tol</span><span class="special">,</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&</span> <span class="identifier">max_iter</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</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">,</span> <span class="keyword">class</span> <span class="identifier">Tol</span><span class="special">,</span> <span class="keyword">class</span> <a class="link" href="../../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">bisect</span><span class="special">(</span> <span class="comment">// Specified policy.</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="identifier">Tol</span> <span class="identifier">tol</span><span class="special">,</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&</span> <span class="identifier">max_iter</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <a class="link" href="../../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&);</span>
|
||||
</pre>
|
||||
<p>
|
||||
These functions locate the root using <a href="https://en.wikipedia.org/wiki/Bisection" target="_top">bisection</a>.
|
||||
</p>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">bisect</span></code> function arguments
|
||||
are:
|
||||
</p>
|
||||
<div class="variablelist">
|
||||
<p class="title"><b></b></p>
|
||||
<dl class="variablelist">
|
||||
<dt><span class="term">f</span></dt>
|
||||
<dd><p>
|
||||
A unary functor which is the function <span class="emphasis"><em>f(x)</em></span> whose
|
||||
root is to be found.
|
||||
</p></dd>
|
||||
<dt><span class="term">min</span></dt>
|
||||
<dd><p>
|
||||
The left bracket of the interval known to contain the root.
|
||||
</p></dd>
|
||||
<dt><span class="term">max</span></dt>
|
||||
<dd><p>
|
||||
The right bracket of the interval known to contain the root.<br>
|
||||
It is a precondition that <span class="emphasis"><em>min < max</em></span> and
|
||||
<span class="emphasis"><em>f(min)*f(max) <= 0</em></span>, the function raises an
|
||||
<a class="link" href="../../error_handling.html#math_toolkit.error_handling.evaluation_error">evaluation_error</a>
|
||||
if these preconditions are violated. The action taken on error is
|
||||
controlled by the <a class="link" href="../../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">Policy</a> template argument:
|
||||
the default behavior is to throw a <span class="emphasis"><em>boost::math::evaluation_error</em></span>.
|
||||
If the <a class="link" href="../../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">Policy</a> is changed to not throw
|
||||
then it returns <span class="emphasis"><em>std::pair<T>(min, min)</em></span>.
|
||||
</p></dd>
|
||||
<dt><span class="term">tol</span></dt>
|
||||
<dd><p>
|
||||
A binary functor that specifies the termination condition: the function
|
||||
will return the current brackets enclosing the root when <span class="emphasis"><em>tol(min,
|
||||
max)</em></span> becomes true. See also <a class="link" href="root_termination.html" title="Termination Condition Functors">predefined
|
||||
termination functors</a>.
|
||||
</p></dd>
|
||||
<dt><span class="term">max_iter</span></dt>
|
||||
<dd><p>
|
||||
The maximum number of invocations of <span class="emphasis"><em>f(x)</em></span> to
|
||||
make while searching for the root. On exit, this is updated to the
|
||||
actual number of invocations performed.
|
||||
</p></dd>
|
||||
</dl>
|
||||
</div>
|
||||
<p>
|
||||
The final <a class="link" href="../../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">Policy</a> argument is optional and
|
||||
can be used to control the behaviour of the function: how it handles errors,
|
||||
what level of precision to use etc. Refer to the <a class="link" href="../../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">policy
|
||||
documentation for more details</a>.
|
||||
</p>
|
||||
<p>
|
||||
<span class="bold"><strong>Returns</strong></span>: a pair of values <span class="emphasis"><em>r</em></span>
|
||||
that bracket the root so that:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">f</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="special">*</span> <span class="identifier">f</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="special"><=</span> <span class="number">0</span>
|
||||
</pre>
|
||||
<p>
|
||||
and either
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">tol</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">r</span><span class="special">.</span><span class="identifier">second</span><span class="special">)</span> <span class="special">==</span> <span class="keyword">true</span>
|
||||
</pre>
|
||||
<p>
|
||||
or
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">max_iter</span> <span class="special">>=</span> <span class="identifier">m</span>
|
||||
</pre>
|
||||
<p>
|
||||
where <span class="emphasis"><em>m</em></span> is the initial value of <span class="emphasis"><em>max_iter</em></span>
|
||||
passed to the function.
|
||||
</p>
|
||||
<p>
|
||||
In other words, it's up to the caller to verify whether termination occurred
|
||||
as a result of exceeding <span class="emphasis"><em>max_iter</em></span> function invocations
|
||||
(easily done by checking the updated value of <span class="emphasis"><em>max_iter</em></span>
|
||||
when the function returns), rather than because the termination condition
|
||||
<span class="emphasis"><em>tol</em></span> was satisfied.
|
||||
</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 © 2006-2010, 2012-2014 Nikhar Agrawal,
|
||||
Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
|
||||
Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan Råde, Gautam Sewani,
|
||||
Benjamin Sobotta, 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.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots_noderiv.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="bracket_solve.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,186 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Bracket and Solve Root</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.5.1">
|
||||
<link rel="up" href="../roots_noderiv.html" title="Root Finding Without Derivatives">
|
||||
<link rel="prev" href="bisect.html" title="Bisection">
|
||||
<link rel="next" href="TOMS748.html" title="Algorithm TOMS 748: Alefeld, Potra and Shi: Enclosing zeros of continuous functions">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="bisect.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots_noderiv.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="TOMS748.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="math_toolkit.roots.roots_noderiv.bracket_solve"></a><a class="link" href="bracket_solve.html" title="Bracket and Solve Root">Bracket
|
||||
and Solve Root</a>
|
||||
</h4></div></div></div>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</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">,</span> <span class="keyword">class</span> <span class="identifier">Tol</span><span class="special">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">bracket_and_solve_root</span><span class="special">(</span>
|
||||
<span class="identifier">F</span> <span class="identifier">f</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">guess</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">factor</span><span class="special">,</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">rising</span><span class="special">,</span>
|
||||
<span class="identifier">Tol</span> <span class="identifier">tol</span><span class="special">,</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&</span> <span class="identifier">max_iter</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</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">,</span> <span class="keyword">class</span> <span class="identifier">Tol</span><span class="special">,</span> <span class="keyword">class</span> <a class="link" href="../../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">bracket_and_solve_root</span><span class="special">(</span>
|
||||
<span class="identifier">F</span> <span class="identifier">f</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">guess</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">factor</span><span class="special">,</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">rising</span><span class="special">,</span>
|
||||
<span class="identifier">Tol</span> <span class="identifier">tol</span><span class="special">,</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&</span> <span class="identifier">max_iter</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <a class="link" href="../../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&);</span>
|
||||
</pre>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">bracket_and_solve_root</span></code>
|
||||
is a convenience function that calls <a class="link" href="TOMS748.html" title="Algorithm TOMS 748: Alefeld, Potra and Shi: Enclosing zeros of continuous functions">TOMS
|
||||
748 algorithm</a> internally to find the root of <span class="emphasis"><em>f(x)</em></span>.
|
||||
It is generally much easier to use this function rather than <a class="link" href="TOMS748.html" title="Algorithm TOMS 748: Alefeld, Potra and Shi: Enclosing zeros of continuous functions">TOMS
|
||||
748 algorithm</a>, since it does the hard work of bracketing the root
|
||||
for you. It's bracketing routines are quite robust and will usually be
|
||||
more foolproof than home-grown routines, unless the function can be analysed
|
||||
to yield tight brackets.
|
||||
</p>
|
||||
<p>
|
||||
Note that this routine can only be used when:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<span class="emphasis"><em>f(x)</em></span> is monotonic in the half of the real axis
|
||||
containing <span class="emphasis"><em>guess</em></span>.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
The value of the inital guess must have the same sign as the root:
|
||||
the function will <span class="emphasis"><em>never cross the origin</em></span> when
|
||||
searching for the root.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
The location of the root should be known at least approximately, if
|
||||
the location of the root differs by many orders of magnitude from
|
||||
<span class="emphasis"><em>guess</em></span> then many iterations will be needed to bracket
|
||||
the root in spite of the special heuristics used to guard against this
|
||||
very situation. A typical example would be setting the initial guess
|
||||
to 0.1, when the root is at 1e-300.
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
The <code class="computeroutput"><span class="identifier">bracket_and_solve_root</span></code>
|
||||
parameters are:
|
||||
</p>
|
||||
<div class="variablelist">
|
||||
<p class="title"><b></b></p>
|
||||
<dl class="variablelist">
|
||||
<dt><span class="term">f</span></dt>
|
||||
<dd><p>
|
||||
A unary functor that is the function whose root is to be solved.
|
||||
<span class="emphasis"><em>f(x)</em></span> must be uniformly increasing or decreasing
|
||||
on <span class="emphasis"><em>x</em></span>.
|
||||
</p></dd>
|
||||
<dt><span class="term">guess</span></dt>
|
||||
<dd><p>
|
||||
An initial approximation to the root.
|
||||
</p></dd>
|
||||
<dt><span class="term">factor</span></dt>
|
||||
<dd><p>
|
||||
A scaling factor that is used to bracket the root: the value <span class="emphasis"><em>guess</em></span>
|
||||
is multiplied (or divided as appropriate) by <span class="emphasis"><em>factor</em></span>
|
||||
until two values are found that bracket the root. A value such as
|
||||
2 is a typical choice for <span class="emphasis"><em>factor</em></span>. In addition
|
||||
<span class="emphasis"><em>factor</em></span> will be multiplied by 2 every 32 iterations:
|
||||
this is to guard against a really very bad initial guess, typically
|
||||
these occur when it's known the result is very large or small, but
|
||||
not the exact order of magnitude.
|
||||
</p></dd>
|
||||
<dt><span class="term">rising</span></dt>
|
||||
<dd><p>
|
||||
Set to <span class="emphasis"><em>true</em></span> if <span class="emphasis"><em>f(x)</em></span> is
|
||||
rising on <span class="emphasis"><em>x</em></span> and <span class="emphasis"><em>false</em></span> if
|
||||
<span class="emphasis"><em>f(x)</em></span> is falling on <span class="emphasis"><em>x</em></span>. This
|
||||
value is used along with the result of <span class="emphasis"><em>f(guess)</em></span>
|
||||
to determine if <span class="emphasis"><em>guess</em></span> is above or below the
|
||||
root.
|
||||
</p></dd>
|
||||
<dt><span class="term">tol</span></dt>
|
||||
<dd><p>
|
||||
A binary functor that determines the termination condition for the
|
||||
search for the root. <span class="emphasis"><em>tol</em></span> is passed the current
|
||||
brackets at each step, when it returns true then the current brackets
|
||||
are returned as the pair result. See also <a class="link" href="root_termination.html" title="Termination Condition Functors">predefined
|
||||
termination functors</a>.
|
||||
</p></dd>
|
||||
<dt><span class="term">max_iter</span></dt>
|
||||
<dd><p>
|
||||
The maximum number of function invocations to perform in the search
|
||||
for the root. On exit is set to the actual number of invocations
|
||||
performed.
|
||||
</p></dd>
|
||||
</dl>
|
||||
</div>
|
||||
<p>
|
||||
The final <a class="link" href="../../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">Policy</a> argument is optional and
|
||||
can be used to control the behaviour of the function: how it handles errors,
|
||||
what level of precision to use etc. Refer to the <a class="link" href="../../../policy.html" title="Chapter 15. Policies: Controlling Precision, Error Handling etc">policy
|
||||
documentation for more details</a>.
|
||||
</p>
|
||||
<p>
|
||||
<span class="bold"><strong>Returns</strong></span>: a pair of values <span class="emphasis"><em>r</em></span>
|
||||
that bracket the root so that:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">f</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="special">*</span> <span class="identifier">f</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="special"><=</span> <span class="number">0</span>
|
||||
</pre>
|
||||
<p>
|
||||
and either
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">tol</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">r</span><span class="special">.</span><span class="identifier">second</span><span class="special">)</span> <span class="special">==</span> <span class="keyword">true</span>
|
||||
</pre>
|
||||
<p>
|
||||
or
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">max_iter</span> <span class="special">>=</span> <span class="identifier">m</span>
|
||||
</pre>
|
||||
<p>
|
||||
where <span class="emphasis"><em>m</em></span> is the initial value of <span class="emphasis"><em>max_iter</em></span>
|
||||
passed to the function.
|
||||
</p>
|
||||
<p>
|
||||
In other words, it's up to the caller to verify whether termination occurred
|
||||
as a result of exceeding <span class="emphasis"><em>max_iter</em></span> function invocations
|
||||
(easily done by checking the value of <span class="emphasis"><em>max_iter</em></span> when
|
||||
the function returns), rather than because the termination condition <span class="emphasis"><em>tol</em></span>
|
||||
was satisfied.
|
||||
</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 © 2006-2010, 2012-2014 Nikhar Agrawal,
|
||||
Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
|
||||
Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan Råde, Gautam Sewani,
|
||||
Benjamin Sobotta, 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="bisect.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots_noderiv.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="TOMS748.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,54 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Brent-Decker 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.5.1">
|
||||
<link rel="up" href="../roots_noderiv.html" title="Root Finding Without Derivatives">
|
||||
<link rel="prev" href="TOMS748.html" title="Algorithm TOMS 748: Alefeld, Potra and Shi: Enclosing zeros of continuous functions">
|
||||
<link rel="next" href="root_termination.html" title="Termination Condition Functors">
|
||||
</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="TOMS748.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots_noderiv.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_termination.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="math_toolkit.roots.roots_noderiv.brent"></a><a class="link" href="brent.html" title="Brent-Decker Algorithm">Brent-Decker
|
||||
Algorithm</a>
|
||||
</h4></div></div></div>
|
||||
<p>
|
||||
The <a href="http://en.wikipedia.org/wiki/Brent%27s_method" target="_top">Brent-Dekker
|
||||
algorithm</a>, although very well know, is not provided by this library
|
||||
as <a class="link" href="TOMS748.html" title="Algorithm TOMS 748: Alefeld, Potra and Shi: Enclosing zeros of continuous functions">TOMS 748 algorithm</a>
|
||||
or its slightly easier to use variant <a class="link" href="bracket_solve.html" title="Bracket and Solve Root">bracket
|
||||
and solve</a> are superior and provide equivalent functionality.
|
||||
</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 © 2006-2010, 2012-2014 Nikhar Agrawal,
|
||||
Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
|
||||
Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan Råde, Gautam Sewani,
|
||||
Benjamin Sobotta, 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="TOMS748.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots_noderiv.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_termination.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,63 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Implementation</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.5.1">
|
||||
<link rel="up" href="../roots_noderiv.html" title="Root Finding Without Derivatives">
|
||||
<link rel="prev" href="root_termination.html" title="Termination Condition Functors">
|
||||
<link rel="next" href="../roots_deriv.html" title="Root Finding With Derivatives: Newton-Raphson, Halley & Schröder">
|
||||
</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="root_termination.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots_noderiv.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="../roots_deriv.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="math_toolkit.roots.roots_noderiv.implementation"></a><a class="link" href="implementation.html" title="Implementation">Implementation</a>
|
||||
</h4></div></div></div>
|
||||
<p>
|
||||
The implementation of the bisection algorithm is extremely straightforward
|
||||
and not detailed here.
|
||||
</p>
|
||||
<p>
|
||||
<a href="http://portal.acm.org/citation.cfm?id=210111" target="_top">TOMS Algorithm
|
||||
748: enclosing zeros of continuous functions</a> is described in detail
|
||||
in:
|
||||
</p>
|
||||
<p>
|
||||
<span class="emphasis"><em>Algorithm 748: Enclosing Zeros of Continuous Functions, G. E.
|
||||
Alefeld, F. A. Potra and Yixun Shi, ACM Transactions on Mathematica1 Software,
|
||||
Vol. 21. No. 3. September 1995. Pages 327-344.</em></span>
|
||||
</p>
|
||||
<p>
|
||||
The implementation here is a faithful translation of this paper into C++.
|
||||
</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 © 2006-2010, 2012-2014 Nikhar Agrawal,
|
||||
Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
|
||||
Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan Råde, Gautam Sewani,
|
||||
Benjamin Sobotta, 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="root_termination.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots_noderiv.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="../roots_deriv.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,102 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Termination Condition Functors</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.5.1">
|
||||
<link rel="up" href="../roots_noderiv.html" title="Root Finding Without Derivatives">
|
||||
<link rel="prev" href="brent.html" title="Brent-Decker Algorithm">
|
||||
<link rel="next" href="implementation.html" title="Implementation">
|
||||
</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="brent.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots_noderiv.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="implementation.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="math_toolkit.roots.roots_noderiv.root_termination"></a><a class="link" href="root_termination.html" title="Termination Condition Functors">Termination
|
||||
Condition Functors</a>
|
||||
</h4></div></div></div>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">eps_tolerance</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">eps_tolerance</span><span class="special">();</span>
|
||||
<span class="identifier">eps_tolerance</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">bits</span><span class="special">);</span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">b</span><span class="special">)</span><span class="keyword">const</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">eps_tolerance</span></code> is the usual
|
||||
termination condition used with these root finding functions. Its <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code>
|
||||
will return true when the relative distance between <span class="emphasis"><em>a</em></span>
|
||||
and <span class="emphasis"><em>b</em></span> is less than four times the machine epsilon
|
||||
for T, or 2<sup>1-bits</sup>, whichever is the larger. In other words, you set <span class="emphasis"><em>bits</em></span>
|
||||
to the number of bits of precision you want in the result. The minimal
|
||||
tolerance of <span class="emphasis"><em>four times the machine epsilon of type T</em></span>
|
||||
is required to ensure that we get back a bracketing interval, since this
|
||||
must clearly be at greater than one epsilon in size. While in theory a
|
||||
maximum distance of twice machine epsilon is possible to achieve, in practice
|
||||
this results in a great deal of "thrashing" given that the function
|
||||
whose root is being found can only ever be accurate to 1 epsilon at best.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">equal_floor</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">equal_floor</span><span class="special">();</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">b</span><span class="special">)</span><span class="keyword">const</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
This termination condition is used when you want to find an integer result
|
||||
that is the <span class="emphasis"><em>floor</em></span> of the true root. It will terminate
|
||||
as soon as both ends of the interval have the same <span class="emphasis"><em>floor</em></span>.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">equal_ceil</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">equal_ceil</span><span class="special">();</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">b</span><span class="special">)</span><span class="keyword">const</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
This termination condition is used when you want to find an integer result
|
||||
that is the <span class="emphasis"><em>ceil</em></span> of the true root. It will terminate
|
||||
as soon as both ends of the interval have the same <span class="emphasis"><em>ceil</em></span>.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">equal_nearest_integer</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">equal_nearest_integer</span><span class="special">();</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">b</span><span class="special">)</span><span class="keyword">const</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
This termination condition is used when you want to find an integer result
|
||||
that is the <span class="emphasis"><em>closest</em></span> to the true root. It will terminate
|
||||
as soon as both ends of the interval round to the same nearest integer.
|
||||
</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 © 2006-2010, 2012-2014 Nikhar Agrawal,
|
||||
Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
|
||||
Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan Råde, Gautam Sewani,
|
||||
Benjamin Sobotta, 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="brent.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../roots_noderiv.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="implementation.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user