mirror of
https://github.com/boostorg/math.git
synced 2026-01-19 04:22:09 +00:00
486 lines
55 KiB
HTML
486 lines
55 KiB
HTML
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
<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 3.0.0">
|
|
<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><h3 class="title">
|
|
<a name="math_toolkit.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>
|
|
</h3></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>
|
|
<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">pow</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// boost::math::pow<5,double></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>
|
|
<div class="blockquote"><blockquote class="blockquote"><p>
|
|
<span class="serif_italic"><span class="emphasis"><em>f(x) = x³ -a</em></span></span>
|
|
</p></blockquote></div>
|
|
<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.root_finding_examples.cbrt_eg.h0"></a>
|
|
<span class="phrase"><a name="math_toolkit.root_finding_examples.cbrt_eg.cbrt_no_derivatives"></a></span><a class="link" href="cbrt_eg.html#math_toolkit.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">std</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">std</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">// Initially 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">std</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">std</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.root_finding_examples.cbrt_eg.h1"></a>
|
|
<span class="phrase"><a name="math_toolkit.root_finding_examples.cbrt_eg.cbrt_1st_derivative"></a></span><a class="link" href="cbrt_eg.html#math_toolkit.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">std</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">std</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 choosing 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.root_finding_examples.cbrt_eg.h2"></a>
|
|
<span class="phrase"><a name="math_toolkit.root_finding_examples.cbrt_eg.cbrt_2_derivatives"></a></span><a class="link" href="cbrt_eg.html#math_toolkit.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>
|
|
<div class="blockquote"><blockquote class="blockquote"><p>
|
|
<span class="serif_italic"><span class="emphasis"><em>f''(x) = 6x</em></span></span>
|
|
</p></blockquote></div>
|
|
<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">std</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_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-2021 Nikhar Agrawal, Anton Bikineev, Matthew Borland,
|
|
Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert Holin, Bruno
|
|
Lalande, John Maddock, Evan Miller, Jeremy Murphy, Matthew Pulver, Johan Råde,
|
|
Gautam Sewani, Benjamin Sobotta, Nicholas Thompson, Thijs van den Berg, Daryle
|
|
Walker and Xiaogang Zhang<p>
|
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
|
</p>
|
|
</div></td>
|
|
</tr></table>
|
|
<hr>
|
|
<div class="spirit-nav">
|
|
<a accesskey="p" href="../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>
|