[DEV] add v1.76.0

This commit is contained in:
2021-10-05 21:37:46 +02:00
parent a97e9ae7d4
commit d0115b733d
45133 changed files with 4744437 additions and 1026325 deletions

View File

@@ -0,0 +1,136 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Arithmetic-Geometric Mean</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="../internals.html" title="Internal tools">
<link rel="prev" href="series_evaluation.html" title="Series Evaluation">
<link rel="next" href="cf.html" title="Continued Fraction 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="series_evaluation.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="cf.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.internals.agm"></a><a class="link" href="agm.html" title="Arithmetic-Geometric Mean">Arithmetic-Geometric Mean</a>
</h3></div></div></div>
<h5>
<a name="math_toolkit.internals.agm.h0"></a>
<span class="phrase"><a name="math_toolkit.internals.agm.synopsis"></a></span><a class="link" href="agm.html#math_toolkit.internals.agm.synopsis">Synopsis</a>
</h5>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">tools</span><span class="special">/</span><span class="identifier">agm</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</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">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Real</span><span class="special">&gt;</span>
<span class="identifier">Real</span> <span class="identifier">agm</span><span class="special">(</span><span class="identifier">Real</span> <span class="identifier">a0</span><span class="special">,</span> <span class="identifier">Real</span> <span class="identifier">g0</span><span class="special">);</span>
<span class="special">}</span> <span class="comment">// namespaces</span>
</pre>
<p>
The function <code class="computeroutput"><span class="identifier">agm</span></code> produces
the limiting value of the sequence
</p>
<p>
<span class="inlinemediaobject"><object type="image/svg+xml" data="../../../equations/agm_sequence.svg" width="526" height="36"></object></span>
</p>
<p>
A basic usage is
</p>
<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">G</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">agm</span><span class="special">(</span><span class="identifier">sqrt</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>
</pre>
<p>
The AGM inequality
</p>
<p>
<span class="inlinemediaobject"><object type="image/svg+xml" data="../../../equations/agm_sequence.svg" width="526" height="36"></object></span>
</p>
<p>
shows that
</p>
<p>
<span class="inlinemediaobject"><object type="image/svg+xml" data="../../../equations/agm_bound.svg" width="249" height="18"></object></span>
</p>
<p>
We use this condition internally to measure convergence; however, there is
no need to worry about putting arguments in the correct order since we extend
<code class="computeroutput"><span class="identifier">agm</span></code> to a symmetric function
by definition. Both arguments must be non-negative, as the sequence becomes
complex for negative arguments. (We have not implemented the complex-valued
AGM sequence.) The function <code class="computeroutput"><span class="identifier">agm</span></code>
is "essentially" one-dimensional, as the scale invariance <code class="computeroutput"><span class="identifier">agm</span><span class="special">(</span><span class="identifier">k</span><span class="special">*</span><span class="identifier">x</span><span class="special">,</span>
<span class="identifier">k</span><span class="special">*</span><span class="identifier">y</span><span class="special">)</span> <span class="special">==</span>
<span class="identifier">k</span><span class="special">*</span><span class="identifier">agm</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span><span class="identifier">y</span><span class="special">)</span></code>
always allows us to take one argument to be unity. The following ULP plot
has been generated with the function <code class="computeroutput"><span class="identifier">agm</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span>
<span class="identifier">Real</span><span class="special">(</span><span class="number">1</span><span class="special">))</span></code>:
</p>
<p>
<span class="inlinemediaobject"><object type="image/svg+xml" data="../../../graphs/agm_ulps_plot.svg"></object></span>
</p>
<p>
The graph above shows an ulps plot of the Boost implementation of <code class="computeroutput"><span class="identifier">agm</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">Real</span><span class="special">(</span><span class="number">1</span><span class="special">))</span></code>.
An ~2 ULP bound is to be expected.
</p>
<p>
A google benchmark for various types is available in <code class="computeroutput"><span class="identifier">boost</span><span class="special">/</span><span class="identifier">libs</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">reporting</span><span class="special">/</span><span class="identifier">performance</span><span class="special">/</span><span class="identifier">test_agm</span><span class="special">.</span><span class="identifier">cpp</span></code>; some
results on a consumer laptop are provided for convenience:
</p>
<pre class="programlisting"><span class="identifier">Run</span> <span class="identifier">on</span> <span class="special">(</span><span class="number">16</span> <span class="identifier">X</span> <span class="number">2300</span> <span class="identifier">MHz</span> <span class="identifier">CPU</span> <span class="identifier">s</span><span class="special">)</span>
<span class="identifier">CPU</span> <span class="identifier">Caches</span><span class="special">:</span>
<span class="identifier">L1</span> <span class="identifier">Data</span> <span class="number">32</span><span class="identifier">K</span> <span class="special">(</span><span class="identifier">x8</span><span class="special">)</span>
<span class="identifier">L1</span> <span class="identifier">Instruction</span> <span class="number">32</span><span class="identifier">K</span> <span class="special">(</span><span class="identifier">x8</span><span class="special">)</span>
<span class="identifier">L2</span> <span class="identifier">Unified</span> <span class="number">262</span><span class="identifier">K</span> <span class="special">(</span><span class="identifier">x8</span><span class="special">)</span>
<span class="identifier">L3</span> <span class="identifier">Unified</span> <span class="number">16777</span><span class="identifier">K</span> <span class="special">(</span><span class="identifier">x1</span><span class="special">)</span>
<span class="identifier">Load</span> <span class="identifier">Average</span><span class="special">:</span> <span class="number">2.02</span><span class="special">,</span> <span class="number">2.14</span><span class="special">,</span> <span class="number">2.00</span>
<span class="special">-------------------------------------------------------------------------------</span>
<span class="identifier">Benchmark</span> <span class="identifier">Time</span> <span class="identifier">CPU</span> <span class="identifier">Iterations</span>
<span class="special">-------------------------------------------------------------------------------</span>
<span class="identifier">AGM</span><span class="special">&lt;</span><span class="keyword">float</span><span class="special">&gt;</span> <span class="number">8.52</span> <span class="identifier">ns</span> <span class="number">8.51</span> <span class="identifier">ns</span> <span class="number">59654685</span>
<span class="identifier">AGM</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="number">13.5</span> <span class="identifier">ns</span> <span class="number">13.5</span> <span class="identifier">ns</span> <span class="number">51709746</span>
<span class="identifier">AGM</span><span class="special">&lt;</span><span class="keyword">long</span> <span class="keyword">double</span><span class="special">&gt;</span> <span class="number">30.6</span> <span class="identifier">ns</span> <span class="number">30.6</span> <span class="identifier">ns</span> <span class="number">18745247</span>
<span class="identifier">AGM</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">float128</span><span class="special">&gt;</span> <span class="number">2332</span> <span class="identifier">ns</span> <span class="number">2332</span> <span class="identifier">ns</span> <span class="number">299303</span>
</pre>
<p>
If any inputs are NaNs, the result is a NaN. If any inputs are +∞, the
result is +∞, unless the other argument fails NaN or negative validation.
</p>
<h5>
<a name="math_toolkit.internals.agm.h1"></a>
<span class="phrase"><a name="math_toolkit.internals.agm.references"></a></span><a class="link" href="agm.html#math_toolkit.internals.agm.references">References</a>
</h5>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
Steven R. Finch. <span class="emphasis"><em>Mathematical Constants</em></span> Cambridge,
2003.
</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-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="series_evaluation.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="cf.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,107 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Centered Continued Fractions</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="../internals.html" title="Internal tools">
<link rel="prev" href="simple_continued_fraction.html" title="Simple Continued Fractions">
<link rel="next" href="luroth_expansion.html" title="Luroth Expansions">
</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="simple_continued_fraction.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="luroth_expansion.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.internals.centered_continued_fraction"></a><a class="link" href="centered_continued_fraction.html" title="Centered Continued Fractions">Centered
Continued Fractions</a>
</h3></div></div></div>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">tools</span><span class="special">/</span><span class="identifier">centered_continued_fraction</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</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">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Real</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Z</span> <span class="special">=</span> <span class="identifier">int64_t</span><span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">centered_continued_fraction</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="identifier">centered_continued_fraction</span><span class="special">(</span><span class="identifier">Real</span> <span class="identifier">x</span><span class="special">);</span>
<span class="identifier">Real</span> <span class="identifier">khinchin_geometric_mean</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Z_</span><span class="special">&gt;</span>
<span class="keyword">friend</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">&lt;&lt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="identifier">out</span><span class="special">,</span> <span class="identifier">centered_continued_fraction</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Z_</span><span class="special">&gt;&amp;</span> <span class="identifier">ccf</span><span class="special">);</span>
<span class="special">};</span>
<span class="special">}</span>
</pre>
<p>
The <code class="computeroutput"><span class="identifier">centered_continued_fraction</span></code>
class provided by Boost affords the ability to convert a floating point number
into a centered continued fraction. Unlike the simple continued fraction,
a centered continued fraction allows partial denominators to be negative.
</p>
<p>
Here's a minimal working example:
</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">constants</span><span class="special">::</span><span class="identifier">pi</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">centered_continued_fraction</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">cfrac</span> <span class="special">=</span> <span class="identifier">centered_continued_fraction</span><span class="special">(</span><span class="identifier">pi</span><span class="special">&lt;</span><span class="keyword">long</span> <span class="keyword">double</span><span class="special">&gt;());</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"π ≈ "</span> <span class="special">&lt;&lt;</span> <span class="identifier">cfrac</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
<span class="comment">// Prints:</span>
<span class="comment">// π ≈ [3; 7, 16, -294, 3, -4, 5, -15, -3, 2, 2]</span>
</pre>
<p>
This function achieves the same end as the Maple syntax
</p>
<p>
<span class="inlinemediaobject"><img src="../../../images/maple_cfrac.png"></span>
</p>
<p>
You should convince yourself that the Maple output and the notation we use
are in fact the same thing.
</p>
<p>
The class computes partial denominators which simultaneously computing convergents
with the modified Lentz's algorithm. Once a convergent is within a few ulps
of the input value, the computation stops.
</p>
<p>
Just like simple continued fractions, centered continued fractions admit
a "Khinchin constant". The value of this constant is ~5.454517
(see <a href="http://jeremiebourdon.free.fr/data/Khintchine.pdf" target="_top">here</a>).
We can evaluate the "empirical Khinchin constant" for a particular
number via
</p>
<pre class="programlisting"><span class="identifier">cfrac</span><span class="special">.</span><span class="identifier">khinchin_geometric_mean</span><span class="special">();</span>
</pre>
<p>
If this is close to 5.454517, then the number is probably uninteresting with
respect to its characterization as a centered continued fraction.
</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="simple_continued_fraction.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="luroth_expansion.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -1,13 +1,13 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Continued Fraction 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.6.0">
<link rel="home" href="../../index.html" title="Math Toolkit 3.0.0">
<link rel="up" href="../internals.html" title="Internal tools">
<link rel="prev" href="series_evaluation.html" title="Series Evaluation">
<link rel="next" href="tuples.html" title="Tuples">
<link rel="prev" href="agm.html" title="Arithmetic-Geometric Mean">
<link rel="next" href="simple_continued_fraction.html" title="Simple Continued Fractions">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
@@ -20,7 +20,7 @@
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="series_evaluation.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="tuples.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
<a accesskey="p" href="agm.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="simple_continued_fraction.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
@@ -81,15 +81,17 @@
the continued fraction described by the <span class="emphasis"><em>generator</em></span> type
argument. The functions with an "_a" suffix evaluate the fraction:
</p>
<p>
<span class="inlinemediaobject"><img src="../../../equations/fraction2.svg"></span>
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="inlinemediaobject"><img src="../../../equations/fraction2.svg"></span>
</p></blockquote></div>
<p>
and those with a "_b" suffix evaluate the fraction:
</p>
<p>
<span class="inlinemediaobject"><img src="../../../equations/fraction1.svg"></span>
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="inlinemediaobject"><img src="../../../equations/fraction1.svg"></span>
</p></blockquote></div>
<p>
This latter form is somewhat more natural in that it corresponds with the
usual definition of a continued fraction, but note that the first <span class="emphasis"><em>a</em></span>
@@ -129,8 +131,8 @@
<td>
<p>
The type that is the result of invoking operator(). This can be
either an arithmetic type, or a std::pair&lt;&gt; of arithmetic
types.
either an arithmetic or complex type, or a std::pair&lt;&gt; of
arithmetic or complex types.
</p>
</td>
</tr>
@@ -184,14 +186,18 @@
<a name="math_toolkit.internals.cf.h3"></a>
<span class="phrase"><a name="math_toolkit.internals.cf.examples"></a></span><a class="link" href="cf.html#math_toolkit.internals.cf.examples">Examples</a>
</h5>
<p>
All of these examples are in <a href="../../../../example/continued_fractions.cpp" target="_top">continued_fractions.cpp</a>.
</p>
<p>
The <a href="http://en.wikipedia.org/wiki/Golden_ratio" target="_top">golden ratio phi
= 1.618033989...</a> can be computed from the simplest continued fraction
of all:
</p>
<p>
<span class="inlinemediaobject"><img src="../../../equations/fraction3.svg"></span>
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="inlinemediaobject"><img src="../../../equations/fraction3.svg"></span>
</p></blockquote></div>
<p>
We begin by defining a generator function:
</p>
@@ -200,7 +206,7 @@
<span class="special">{</span>
<span class="keyword">typedef</span> <span class="identifier">T</span> <span class="identifier">result_type</span><span class="special">;</span>
<span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()</span>
<span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()()</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="number">1</span><span class="special">;</span>
<span class="special">}</span>
@@ -209,18 +215,21 @@
<p>
The golden ratio can then be computed to double precision using:
</p>
<pre class="programlisting"><span class="identifier">continued_fraction_a</span><span class="special">(</span>
<span class="identifier">golden_ratio_fraction</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;(),</span>
<pre class="programlisting"><span class="identifier">golden_ratio_fraction</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">func</span><span class="special">;</span>
<span class="keyword">double</span> <span class="identifier">gr</span> <span class="special">=</span> <span class="identifier">continued_fraction_a</span><span class="special">(</span>
<span class="identifier">func</span><span class="special">,</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">epsilon</span><span class="special">());</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"The golden ratio is: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">gr</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
</pre>
<p>
It's more usual though to have to define both the <span class="emphasis"><em>a</em></span>'s
and the <span class="emphasis"><em>b</em></span>'s when evaluating special functions by continued
fractions, for example the tan function is defined by:
</p>
<p>
<span class="inlinemediaobject"><img src="../../../equations/fraction4.svg"></span>
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="inlinemediaobject"><img src="../../../equations/fraction4.svg"></span>
</p></blockquote></div>
<p>
So its generator object would look like:
</p>
@@ -231,12 +240,12 @@
<span class="identifier">T</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">;</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="identifier">tan_fraction</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">v</span><span class="special">)</span>
<span class="special">:</span> <span class="identifier">a</span><span class="special">(-</span><span class="identifier">v</span><span class="special">*</span><span class="identifier">v</span><span class="special">),</span> <span class="identifier">b</span><span class="special">(-</span><span class="number">1</span><span class="special">)</span>
<span class="special">:</span> <span class="identifier">a</span><span class="special">(-</span><span class="identifier">v</span> <span class="special">*</span> <span class="identifier">v</span><span class="special">),</span> <span class="identifier">b</span><span class="special">(-</span><span class="number">1</span><span class="special">)</span>
<span class="special">{}</span>
<span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">result_type</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">result_type</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span><span class="special">()()</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span><span class="special">()()</span>
<span class="special">{</span>
<span class="identifier">b</span> <span class="special">+=</span> <span class="number">2</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">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">);</span>
@@ -261,14 +270,110 @@
evaluate the fraction: we're removing the leading <span class="emphasis"><em>a</em></span>
term during fraction evaluation as it's different from all the others.
</p>
<p>
Now we'll look at a couple of complex number examples, starting with the
exponential integral which can be calculated via:
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="inlinemediaobject"><img src="../../../equations/expint_n_3.svg"></span>
</p></blockquote></div>
<p>
So our functor looks like this:
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">expint_fraction</span>
<span class="special">{</span>
<span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">result_type</span><span class="special">;</span>
<span class="identifier">expint_fraction</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">n_</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">z_</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">b</span><span class="special">(</span><span class="identifier">z_</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">i</span><span class="special">(-</span><span class="number">1</span><span class="special">),</span> <span class="identifier">n</span><span class="special">(</span><span class="identifier">n_</span><span class="special">)</span> <span class="special">{}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span><span class="special">()()</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_pair</span><span class="special">(-</span><span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;((</span><span class="identifier">i</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">n</span> <span class="special">+</span> <span class="identifier">i</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="number">2</span><span class="special">;</span>
<span class="special">++</span><span class="identifier">i</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="keyword">private</span><span class="special">:</span>
<span class="identifier">T</span> <span class="identifier">b</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span>
<span class="keyword">unsigned</span> <span class="identifier">n</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<p>
We can finish the example by wrapping everything up in a function:
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">inline</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">expint_as_fraction</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">n</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">z</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span> <span class="identifier">max_iter</span> <span class="special">=</span> <span class="number">1000</span><span class="special">;</span>
<span class="identifier">expint_fraction</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">n</span><span class="special">,</span> <span class="identifier">z</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">tools</span><span class="special">::</span><span class="identifier">continued_fraction_b</span><span class="special">(</span>
<span class="identifier">f</span><span class="special">,</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">epsilon</span><span class="special">()),</span>
<span class="identifier">max_iter</span><span class="special">);</span>
<span class="identifier">result</span> <span class="special">=</span> <span class="identifier">exp</span><span class="special">(-</span><span class="identifier">z</span><span class="special">)</span> <span class="special">/</span> <span class="identifier">result</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>
Notice how the termination condition is still expressed as a complex number,
albeit one with zero imaginary part.
</p>
<p>
Our final example will use <code class="literal">continued_fraction_a</code>, in fact
there is only one special function in our code which uses that variant, and
it's the upper incomplete gamma function (Q), which can be calculated via:
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="inlinemediaobject"><img src="../../../equations/igamma9.svg"></span>
</p></blockquote></div>
<p>
In this case the first couple of terms are different from the rest, so our
fraction will start with the first "regular" a term:
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">upper_incomplete_gamma_fract</span>
<span class="special">{</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">T</span><span class="special">::</span><span class="identifier">value_type</span> <span class="identifier">scalar_type</span><span class="special">;</span>
<span class="identifier">T</span> <span class="identifier">z</span><span class="special">,</span> <span class="identifier">a</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">k</span><span class="special">;</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">result_type</span><span class="special">;</span>
<span class="identifier">upper_incomplete_gamma_fract</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">a1</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">z1</span><span class="special">)</span>
<span class="special">:</span> <span class="identifier">z</span><span class="special">(</span><span class="identifier">z1</span> <span class="special">-</span> <span class="identifier">a1</span> <span class="special">+</span> <span class="identifier">scalar_type</span><span class="special">(</span><span class="number">1</span><span class="special">)),</span> <span class="identifier">a</span><span class="special">(</span><span class="identifier">a1</span><span class="special">),</span> <span class="identifier">k</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">result_type</span> <span class="keyword">operator</span><span class="special">()()</span>
<span class="special">{</span>
<span class="special">++</span><span class="identifier">k</span><span class="special">;</span>
<span class="identifier">z</span> <span class="special">+=</span> <span class="identifier">scalar_type</span><span class="special">(</span><span class="number">2</span><span class="special">);</span>
<span class="keyword">return</span> <span class="identifier">result_type</span><span class="special">(</span><span class="identifier">scalar_type</span><span class="special">(</span><span class="identifier">k</span><span class="special">)</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">a</span> <span class="special">-</span> <span class="identifier">scalar_type</span><span class="special">(</span><span class="identifier">k</span><span class="special">)),</span> <span class="identifier">z</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
So now we can implement Q, this time using <code class="literal">continued_fraction_a</code>:
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">inline</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">gamma_Q_as_fraction</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">z</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">upper_incomplete_gamma_fract</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">z</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">eps</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">epsilon</span><span class="special">());</span>
<span class="keyword">return</span> <span class="identifier">pow</span><span class="special">(</span><span class="identifier">z</span><span class="special">,</span> <span class="identifier">a</span><span class="special">)</span> <span class="special">/</span> <span class="special">(</span><span class="identifier">exp</span><span class="special">(</span><span class="identifier">z</span><span class="special">)</span> <span class="special">*(</span><span class="identifier">z</span> <span class="special">-</span> <span class="identifier">a</span> <span class="special">+</span> <span class="identifier">T</span><span class="special">(</span><span class="number">1</span><span class="special">)</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">continued_fraction_a</span><span class="special">(</span><span class="identifier">f</span><span class="special">,</span> <span class="identifier">eps</span><span class="special">)));</span>
<span class="special">}</span>
</pre>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2006-2010, 2012-2014, 2017 Nikhar
Agrawal, Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos,
Hubert Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan R&#229;de, Gautam
Sewani, Benjamin Sobotta, Nicholas Thompson, Thijs van den Berg, Daryle Walker
and Xiaogang Zhang<p>
<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>
@@ -276,7 +381,7 @@
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="series_evaluation.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="tuples.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
<a accesskey="p" href="agm.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="simple_continued_fraction.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,171 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Cohen Acceleration</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="../internals.html" title="Internal tools">
<link rel="prev" href="recurrence.html" title="Tools For 3-Term Recurrence Relations">
<link rel="next" href="tuples.html" title="Tuples">
</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="recurrence.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="tuples.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.internals.cohen_acceleration"></a><a class="link" href="cohen_acceleration.html" title="Cohen Acceleration">Cohen Acceleration</a>
</h3></div></div></div>
<h5>
<a name="math_toolkit.internals.cohen_acceleration.h0"></a>
<span class="phrase"><a name="math_toolkit.internals.cohen_acceleration.synopsis"></a></span><a class="link" href="cohen_acceleration.html#math_toolkit.internals.cohen_acceleration.synopsis">Synopsis</a>
</h5>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">tools</span><span class="special">/</span><span class="identifier">cohen_acceleration</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</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">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">G</span><span class="special">&gt;</span>
<span class="keyword">auto</span> <span class="identifier">cohen_acceleration</span><span class="special">(</span><span class="identifier">G</span><span class="special">&amp;</span> <span class="identifier">generator</span><span class="special">,</span> <span class="identifier">int64_t</span> <span class="identifier">n</span> <span class="special">=</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span>
<span class="special">}</span> <span class="comment">// namespaces</span>
</pre>
<p>
The function <code class="computeroutput"><span class="identifier">cohen_acceleration</span></code>
rapidly computes the limiting value of an alternating series via a technique
developed by <a href="https://www.johndcook.com/blog/2020/08/06/cohen-acceleration/" target="_top">Henri
Cohen et al</a>. To compute
</p>
<p>
<span class="inlinemediaobject"><object type="image/svg+xml" data="../../../equations/alternating_series.svg" width="88" height="51"></object></span>
</p>
<p>
we first define a callable that produces <span class="emphasis"><em>a</em></span><sub><span class="emphasis"><em>k</em></span></sub> on
the kth call. For example, suppose we wish to compute
</p>
<p>
<span class="inlinemediaobject"><object type="image/svg+xml" data="../../../equations/zeta_related_alternating.svg" width="168" height="51"></object></span>
</p>
<p>
First, we need to define a callable which returns the requisite terms:
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Real</span><span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">G</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="identifier">G</span><span class="special">(){</span>
<span class="identifier">k_</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
<span class="identifier">Real</span> <span class="keyword">operator</span><span class="special">()()</span> <span class="special">{</span>
<span class="identifier">k_</span> <span class="special">+=</span> <span class="number">1</span><span class="special">;</span>
<span class="keyword">return</span> <span class="number">1</span><span class="special">/(</span><span class="identifier">k_</span><span class="special">*</span><span class="identifier">k_</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="identifier">Real</span> <span class="identifier">k_</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<p>
Then we pass this into the <code class="computeroutput"><span class="identifier">cohen_acceleration</span></code>
function:
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">gen</span> <span class="special">=</span> <span class="identifier">G</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;();</span>
<span class="keyword">double</span> <span class="identifier">computed</span> <span class="special">=</span> <span class="identifier">cohen_acceleration</span><span class="special">(</span><span class="identifier">gen</span><span class="special">);</span>
</pre>
<p>
See <code class="computeroutput"><span class="identifier">cohen_acceleration</span><span class="special">.</span><span class="identifier">cpp</span></code> in the <code class="computeroutput"><span class="identifier">examples</span></code>
directory for more.
</p>
<p>
The number of terms consumed is computed from the error model
</p>
<p>
<span class="inlinemediaobject"><object type="image/svg+xml" data="../../../equations/cohen_acceleration_error_model.svg" width="394" height="47"></object></span>
</p>
<p>
and must be computed <span class="emphasis"><em>a priori</em></span>. If we read the reference
carefully, we notice that this error model is derived under the assumption
that the terms <span class="emphasis"><em>a</em></span><sub><span class="emphasis"><em>k</em></span></sub> are given as the
moments of a positive measure on [0,1]. If this assumption does not hold,
then the number of terms chosen by the method is incorrect. Hence we permit
the user to provide a second argument to specify the number of terms:
</p>
<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">computed</span> <span class="special">=</span> <span class="identifier">cohen_acceleration</span><span class="special">(</span><span class="identifier">gen</span><span class="special">,</span> <span class="number">5</span><span class="special">);</span>
</pre>
<p>
<span class="emphasis"><em>Nota bene</em></span>: When experimenting with this option, we found
that adding more terms was no guarantee of additional accuracy, and could
not find an example where a user-provided number of terms outperformed the
default. In addition, it is easy to generate intermediates which overflow
if we let <span class="emphasis"><em>n</em></span> grow too large. Hence we recommend only
playing with this parameter to <span class="emphasis"><em>decrease</em></span> the default
number of terms to increase speed.
</p>
<h5>
<a name="math_toolkit.internals.cohen_acceleration.h1"></a>
<span class="phrase"><a name="math_toolkit.internals.cohen_acceleration.performance"></a></span><a class="link" href="cohen_acceleration.html#math_toolkit.internals.cohen_acceleration.performance">Performance</a>
</h5>
<p>
To see that Cohen acceleration is in fact faster than naive summation for
the same level of relative accuracy, we can run the <code class="computeroutput"><span class="identifier">reporting</span><span class="special">/</span><span class="identifier">performance</span><span class="special">/</span><span class="identifier">cohen_acceleration_performance</span><span class="special">.</span><span class="identifier">cpp</span></code> file.
This benchmark computes the alternating Basel series discussed above:
</p>
<pre class="programlisting"><span class="identifier">Running</span> <span class="special">./</span><span class="identifier">reporting</span><span class="special">/</span><span class="identifier">performance</span><span class="special">/</span><span class="identifier">cohen_acceleration_performance</span><span class="special">.</span><span class="identifier">x</span>
<span class="identifier">Run</span> <span class="identifier">on</span> <span class="special">(</span><span class="number">16</span> <span class="identifier">X</span> <span class="number">2300</span> <span class="identifier">MHz</span> <span class="identifier">CPU</span> <span class="identifier">s</span><span class="special">)</span>
<span class="identifier">CPU</span> <span class="identifier">Caches</span><span class="special">:</span>
<span class="identifier">L1</span> <span class="identifier">Data</span> <span class="number">32</span> <span class="identifier">KiB</span> <span class="special">(</span><span class="identifier">x8</span><span class="special">)</span>
<span class="identifier">L1</span> <span class="identifier">Instruction</span> <span class="number">32</span> <span class="identifier">KiB</span> <span class="special">(</span><span class="identifier">x8</span><span class="special">)</span>
<span class="identifier">L2</span> <span class="identifier">Unified</span> <span class="number">256</span> <span class="identifier">KiB</span> <span class="special">(</span><span class="identifier">x8</span><span class="special">)</span>
<span class="identifier">L3</span> <span class="identifier">Unified</span> <span class="number">16384</span> <span class="identifier">KiB</span> <span class="special">(</span><span class="identifier">x1</span><span class="special">)</span>
<span class="identifier">Load</span> <span class="identifier">Average</span><span class="special">:</span> <span class="number">4.13</span><span class="special">,</span> <span class="number">3.71</span><span class="special">,</span> <span class="number">3.30</span>
<span class="special">-----------------------------------------------------------------</span>
<span class="identifier">Benchmark</span> <span class="identifier">Time</span>
<span class="special">-----------------------------------------------------------------</span>
<span class="identifier">CohenAcceleration</span><span class="special">&lt;</span><span class="keyword">float</span><span class="special">&gt;</span> <span class="number">20.7</span> <span class="identifier">ns</span>
<span class="identifier">CohenAcceleration</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="number">64.6</span> <span class="identifier">ns</span>
<span class="identifier">CohenAcceleration</span><span class="special">&lt;</span><span class="keyword">long</span> <span class="keyword">double</span><span class="special">&gt;</span> <span class="number">115</span> <span class="identifier">ns</span>
<span class="identifier">NaiveSum</span><span class="special">&lt;</span><span class="keyword">float</span><span class="special">&gt;</span> <span class="number">4994</span> <span class="identifier">ns</span>
<span class="identifier">NaiveSum</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="number">112803698</span> <span class="identifier">ns</span>
<span class="identifier">NaiveSum</span><span class="special">&lt;</span><span class="keyword">long</span> <span class="keyword">double</span><span class="special">&gt;</span> <span class="number">5009564877</span> <span class="identifier">ns</span>
</pre>
<p>
In fact not only does the naive sum take orders of magnitude longer to compute,
it is less accurate as well.
</p>
<h5>
<a name="math_toolkit.internals.cohen_acceleration.h2"></a>
<span class="phrase"><a name="math_toolkit.internals.cohen_acceleration.references"></a></span><a class="link" href="cohen_acceleration.html#math_toolkit.internals.cohen_acceleration.references">References</a>
</h5>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
Cohen, Henri, Fernando Rodriguez Villegas, and Don Zagier. <span class="emphasis"><em>Convergence
acceleration of alternating series.</em></span> Experimental mathematics
9.1 (2000): 3-12.
</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-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="recurrence.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="tuples.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,85 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Engel Expansion</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="../internals.html" title="Internal tools">
<link rel="prev" href="luroth_expansion.html" title="Luroth Expansions">
<link rel="next" href="recurrence.html" title="Tools For 3-Term Recurrence Relations">
</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="luroth_expansion.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="recurrence.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.internals.engel_expansion"></a><a class="link" href="engel_expansion.html" title="Engel Expansion">Engel Expansion</a>
</h3></div></div></div>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">tools</span><span class="special">/</span><span class="identifier">engel_expansion</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</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">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Real</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Z</span> <span class="special">=</span> <span class="identifier">int64_t</span><span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">engel_expansion</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="identifier">engel_expansion</span><span class="special">(</span><span class="identifier">Real</span> <span class="identifier">x</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">Z</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">digits</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Z_</span><span class="special">&gt;</span>
<span class="keyword">friend</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">&lt;&lt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="identifier">out</span><span class="special">,</span> <span class="identifier">engel_expansion</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">&gt;&amp;</span> <span class="identifier">engel</span><span class="special">);</span>
<span class="special">};</span>
<span class="special">}</span>
</pre>
<p>
The <code class="computeroutput"><span class="identifier">engel_expansion</span></code> class
provided by Boost converts a floating point number into an <a href="https://en.wikipedia.org/wiki/Engel_expansion" target="_top">Engel
series</a>.
</p>
<p>
Here's a minimal working example:
</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">constants</span><span class="special">::</span><span class="identifier">e</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">engel_expansion</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">engel</span> <span class="special">=</span> <span class="identifier">engel_expansion</span><span class="special">(</span><span class="identifier">e</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;());</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"e ≈ "</span> <span class="special">&lt;&lt;</span> <span class="identifier">engel</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
<span class="comment">// Prints:</span>
<span class="comment">// e ≈ {1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}</span>
</pre>
<p>
The digits of an Engel expansion tend to grow exponentially, so the integer
template option might need to be utilized. For example, we can use a wider
integer type via
</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">checked_int1024_t</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">engel</span> <span class="special">=</span> <span class="identifier">engel_expansion</span><span class="special">&lt;</span><span class="identifier">__float128</span><span class="special">,</span> <span class="identifier">checked_int1024_t</span><span class="special">&gt;(</span><span class="identifier">pi</span><span class="special">&lt;</span><span class="identifier">__float128</span><span class="special">&gt;());</span>
</pre>
</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="luroth_expansion.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="recurrence.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -1,10 +1,10 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Relative Error and Testing</title>
<link rel="stylesheet" href="../../math.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../index.html" title="Math Toolkit 2.6.0">
<link rel="home" href="../../index.html" title="Math Toolkit 3.0.0">
<link rel="up" href="../internals.html" title="Internal tools">
<link rel="prev" href="minimax.html" title="Minimax Approximations and the Remez Algorithm">
<link rel="next" href="test_data.html" title="Graphing, Profiling, and Generating Test Data for Special Functions">
@@ -40,7 +40,7 @@
</tr>
<tr><td align="left" valign="top"><p>
The header <code class="computeroutput"><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">test</span><span class="special">.</span><span class="identifier">hpp</span></code> is located under <code class="computeroutput"><span class="identifier">libs</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">include_private</span></code>
and is not installed to the usual locations by default, you will need to
and is NOT installed to the usual locations by default; you will need to
add <code class="computeroutput"><span class="identifier">libs</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">include_private</span></code> to your compiler's include
path in order to use this header.
</p></td></tr>
@@ -62,9 +62,10 @@
Returns the relative error between <span class="emphasis"><em>a</em></span> and <span class="emphasis"><em>v</em></span>
using the usual formula:
</p>
<p>
<span class="inlinemediaobject"><img src="../../../equations/error1.svg"></span>
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="inlinemediaobject"><img src="../../../equations/error1.svg"></span>
</p></blockquote></div>
<p>
In addition the value returned is zero if:
</p>
@@ -169,10 +170,11 @@
<span class="phrase"><a name="math_toolkit.internals.error_test.example"></a></span><a class="link" href="error_test.html#math_toolkit.internals.error_test.example">Example</a>
</h5>
<p>
Suppose we want to test the tgamma and lgamma functions, we can create a
two dimensional matrix of test data, each row is one test case, and contains
three elements: the input value, and the expected results for the tgamma
and lgamma functions respectively.
Suppose we want to test the <code class="computeroutput"><span class="identifier">tgamma</span></code>
and <code class="computeroutput"><span class="identifier">lgamma</span></code> functions, we
can create a two-dimensional matrix of test data, each row is one test case,
and contains three elements: the input value, and the expected results for
the <code class="computeroutput"><span class="identifier">tgamma</span></code> and <code class="computeroutput"><span class="identifier">lgamma</span></code> functions respectively.
</p>
<pre class="programlisting"><span class="keyword">static</span> <span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="identifier">TestType</span><span class="special">,</span> <span class="number">3</span><span class="special">&gt;,</span> <span class="identifier">NumberOfTests</span><span class="special">&gt;</span>
<span class="identifier">factorials</span> <span class="special">=</span> <span class="special">{</span>
@@ -220,11 +222,11 @@
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2006-2010, 2012-2014, 2017 Nikhar
Agrawal, Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos,
Hubert Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan R&#229;de, Gautam
Sewani, Benjamin Sobotta, Nicholas Thompson, Thijs van den Berg, Daryle Walker
and Xiaogang Zhang<p>
<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>

View File

@@ -0,0 +1,117 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Luroth Expansions</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="../internals.html" title="Internal tools">
<link rel="prev" href="centered_continued_fraction.html" title="Centered Continued Fractions">
<link rel="next" href="engel_expansion.html" title="Engel Expansion">
</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="centered_continued_fraction.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="engel_expansion.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.internals.luroth_expansion"></a><a class="link" href="luroth_expansion.html" title="Luroth Expansions">Luroth Expansions</a>
</h3></div></div></div>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">tools</span><span class="special">/</span><span class="identifier">luroth_expansion</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</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">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Real</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Z</span> <span class="special">=</span> <span class="identifier">int64_t</span><span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">luroth_expansion</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="identifier">luroth_expansion</span><span class="special">(</span><span class="identifier">Real</span> <span class="identifier">x</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">Z</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">digits</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">Real</span> <span class="identifier">digit_geometric_mean</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Z_</span><span class="special">&gt;</span>
<span class="keyword">friend</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">&lt;&lt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="identifier">out</span><span class="special">,</span> <span class="identifier">luroth_expansion</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Z_</span><span class="special">&gt;&amp;</span> <span class="identifier">luroth</span><span class="special">);</span>
<span class="special">};</span>
<span class="special">}</span>
</pre>
<p>
The <code class="computeroutput"><span class="identifier">luroth_expansion</span></code> class
provided by Boost expands a floating point number into a Lüroth representation,
i.e.,
</p>
<p>
<span class="inlinemediaobject"><object type="image/svg+xml" data="../../../equations/luroth_expansion.svg" width="457" height="55"></object></span>
</p>
<p>
The numbers <span class="emphasis"><em>d</em></span><sub>i</sub> are called digits or denominators; we
use the terminology digits, since technically in our notation <span class="emphasis"><em>d</em></span><sub>0</sub> is
not a denominator.
</p>
<p>
Here's a minimal working example:
</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">constants</span><span class="special">::</span><span class="identifier">pi</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">luroth_expansion</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">luroth</span> <span class="special">=</span> <span class="identifier">luroth_expansion</span><span class="special">(</span><span class="identifier">pi</span><span class="special">&lt;</span><span class="keyword">long</span> <span class="keyword">double</span><span class="special">&gt;());</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"π ≈ "</span> <span class="special">&lt;&lt;</span> <span class="identifier">luroth</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
<span class="comment">// Prints:</span>
<span class="comment">// π ≈ ((3; 7, 1, 1, 1, 2, 1, 4, 23, 4, 1, 1, 1, 1, 80, 1, 1, 5))</span>
</pre>
<p>
The class computes denominators while simultaneously computing convergents.
Once a convergent is within a few ulps of the input value, the computation
stops.
</p>
<p>
<span class="emphasis"><em>Nota bene:</em></span> There is an alternative definition of the
Lüroth representation where every digit is shifted by 1. We follow the definition
given in Kalpazidou; with the modification that we do not constrain the input
to be in the interval [0,1] and let the first digit be the floor of the input.
</p>
<p>
For almost all real numbers, the geometric mean of the digits converges to
a constant which is approximately 2.2001610580. This is "Khinchin's
constant" for the Lüroth representation.
</p>
<h5>
<a name="math_toolkit.internals.luroth_expansion.h0"></a>
<span class="phrase"><a name="math_toolkit.internals.luroth_expansion.references"></a></span><a class="link" href="luroth_expansion.html#math_toolkit.internals.luroth_expansion.references">References</a>
</h5>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Kalpazidou, Sofia. "Khintchine's constant for Lüroth representation."
Journal of Number Theory 29.2 (1988): 196-205.
</li>
<li class="listitem">
Finch, Steven R. Mathematical constants. Cambridge university press,
2003.
</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-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="centered_continued_fraction.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="engel_expansion.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -1,10 +1,10 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Minimax Approximations and the Remez Algorithm</title>
<link rel="stylesheet" href="../../math.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../index.html" title="Math Toolkit 2.6.0">
<link rel="home" href="../../index.html" title="Math Toolkit 3.0.0">
<link rel="up" href="../internals.html" title="Internal tools">
<link rel="prev" href="tuples.html" title="Tuples">
<link rel="next" href="error_test.html" title="Relative Error and Testing">
@@ -28,12 +28,12 @@
and the Remez Algorithm</a>
</h3></div></div></div>
<p>
The directory libs/math/minimax contains a command line driven program for
the generation of minimax approximations using the Remez algorithm. Both
polynomial and rational approximations are supported, although the latter
are tricky to converge: it is not uncommon for convergence of rational forms
to fail. No such limitations are present for polynomial approximations which
should always converge smoothly.
The directory <code class="computeroutput"><span class="identifier">libs</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">minimax</span></code>
contains an interactive command-line driven program for the generation of
minimax approximations using the Remez algorithm. Both polynomial and rational
approximations are supported, although the latter are tricky to converge:
it is not uncommon for convergence of rational forms to fail. No such limitations
are present for polynomial approximations which should always converge smoothly.
</p>
<p>
It's worth stressing that developing rational approximations to functions
@@ -42,9 +42,9 @@
algorithm is, and the general form of the approximation you want to achieve.
</p>
<p>
Unless you already familar with the Remez method, you should first read the
<a class="link" href="../remez.html" title="The Remez Method">brief background article explaining the
principles behind the Remez algorithm</a>.
Unless you already familiar with the Remez method, you should first read
the <a class="link" href="../remez.html" title="The Remez Method">brief background article explaining
the principles behind the Remez algorithm</a>.
</p>
<p>
The program consists of two parts:
@@ -82,8 +82,9 @@
of the approximation: for example if you are approximating a function <span class="emphasis"><em>f(x)</em></span>
then it is quite common to use:
</p>
<pre class="programlisting"><span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</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="identifier">Y</span> <span class="special">+</span> <span class="identifier">R</span><span class="special">(</span><span class="identifier">x</span><span class="special">))</span>
</pre>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="serif_italic">f(x) = g(x)(Y + R(x))</span>
</p></blockquote></div>
<p>
where <span class="emphasis"><em>g(x)</em></span> is the dominant part of <span class="emphasis"><em>f(x)</em></span>,
<span class="emphasis"><em>Y</em></span> is some constant, and <span class="emphasis"><em>R(x)</em></span> is
@@ -91,7 +92,7 @@
compared to |Y|.
</p>
<p>
In this case you would define <span class="emphasis"><em>f</em></span> to return <span class="emphasis"><em>f(x)/g(x)</em></span>
In this case you would define <span class="emphasis"><em>f</em></span> to return <span class="serif-italic">f(x)/g(x)</span>
and then set the y-offset of the approximation to <span class="emphasis"><em>Y</em></span>
(see command line options below).
</p>
@@ -266,11 +267,11 @@
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2006-2010, 2012-2014, 2017 Nikhar
Agrawal, Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos,
Hubert Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan R&#229;de, Gautam
Sewani, Benjamin Sobotta, Nicholas Thompson, Thijs van den Berg, Daryle Walker
and Xiaogang Zhang<p>
<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>

View File

@@ -0,0 +1,303 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Tools For 3-Term Recurrence Relations</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="../internals.html" title="Internal tools">
<link rel="prev" href="engel_expansion.html" title="Engel Expansion">
<link rel="next" href="cohen_acceleration.html" title="Cohen Acceleration">
</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="engel_expansion.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="cohen_acceleration.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.internals.recurrence"></a><a class="link" href="recurrence.html" title="Tools For 3-Term Recurrence Relations">Tools For 3-Term Recurrence
Relations</a>
</h3></div></div></div>
<h5>
<a name="math_toolkit.internals.recurrence.h0"></a>
<span class="phrase"><a name="math_toolkit.internals.recurrence.synopsis"></a></span><a class="link" href="recurrence.html#math_toolkit.internals.recurrence.synopsis">Synopsis</a>
</h5>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">tools</span><span class="special">/</span><span class="identifier">recurrence</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">math</span><span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">tools</span><span class="special">{</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Recurrence</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="identifier">T</span> <span class="identifier">function_ratio_from_backwards_recurrence</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Recurrence</span><span class="special">&amp;</span> <span class="identifier">r</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">factor</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&amp;</span> <span class="identifier">max_iter</span><span class="special">);</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Recurrence</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="identifier">T</span> <span class="identifier">function_ratio_from_forwards_recurrence</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Recurrence</span><span class="special">&amp;</span> <span class="identifier">r</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">factor</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&amp;</span> <span class="identifier">max_iter</span><span class="special">);</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">NextCoefs</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="identifier">T</span> <span class="identifier">apply_recurrence_relation_forward</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">NextCoefs</span><span class="special">&amp;</span> <span class="identifier">get_coefs</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="identifier">number_of_steps</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">second</span><span class="special">,</span> <span class="keyword">long</span> <span class="keyword">long</span><span class="special">*</span> <span class="identifier">log_scaling</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">T</span><span class="special">*</span> <span class="identifier">previous</span> <span class="special">=</span> <span class="number">0</span><span class="special">);</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">NextCoefs</span><span class="special">&gt;</span>
<span class="identifier">T</span> <span class="identifier">apply_recurrence_relation_backward</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">NextCoefs</span><span class="special">&amp;</span> <span class="identifier">get_coefs</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="identifier">number_of_steps</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">second</span><span class="special">,</span> <span class="keyword">long</span> <span class="keyword">long</span><span class="special">*</span> <span class="identifier">log_scaling</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">T</span><span class="special">*</span> <span class="identifier">previous</span> <span class="special">=</span> <span class="number">0</span><span class="special">);</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Recurrence</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">forward_recurrence_iterator</span><span class="special">;</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Recurrence</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">backward_recurrence_iterator</span><span class="special">;</span>
<span class="special">}}}</span> <span class="comment">// namespaces</span>
</pre>
<h5>
<a name="math_toolkit.internals.recurrence.h1"></a>
<span class="phrase"><a name="math_toolkit.internals.recurrence.description"></a></span><a class="link" href="recurrence.html#math_toolkit.internals.recurrence.description">Description</a>
</h5>
<p>
All of the tools in this header require a description of the recurrence relation:
this takes the form of a functor that returns a tuple containing the 3 coefficients,
specifically, given a recurrence relation:
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="inlinemediaobject"><img src="../../../equations/three_term_recurrence.svg"></span>
</p></blockquote></div>
<p>
And a functor <code class="computeroutput"><span class="identifier">F</span></code> then the
expression:
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="serif_italic">F(n);</span>
</p></blockquote></div>
<p>
Returns a tuple containing <span class="serif_italic">{ a<sub>n</sub>, b<sub>n</sub>, c<sub>n</sub> }</span>.
</p>
<p>
For example, the recurrence relation for the Bessel J and Y functions when
written in this form is:
</p>
<p>
<span class="inlinemediaobject"><object type="image/svg+xml" data="../../../equations/three_term_recurrence_bessel_jy.svg" width="250" height="38"></object></span>
</p>
<p>
Therefore, given local variables <span class="emphasis"><em>x</em></span> and <span class="emphasis"><em>v</em></span>
of type <code class="computeroutput"><span class="keyword">double</span></code> the recurrence
relation for Bessel J and Y can be encoded in a lambda expression like this:
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">recurrence_functor_jy</span> <span class="special">=</span> <span class="special">[&amp;](</span><span class="keyword">int</span> <span class="identifier">n</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="number">1.0</span><span class="special">,</span> <span class="special">-</span><span class="number">2</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">v</span> <span class="special">+</span> <span class="identifier">n</span><span class="special">)</span> <span class="special">/</span> <span class="identifier">x</span><span class="special">,</span> <span class="number">1.0</span><span class="special">);</span> <span class="special">};</span>
</pre>
<p>
Similarly, the Bessel I and K recurrence relation differs just by the sign
of the final term:
</p>
<p>
<span class="inlinemediaobject"><object type="image/svg+xml" data="../../../equations/three_term_recurrence_bessel_ik.svg" width="244" height="38"></object></span>
</p>
<p>
And this could be encoded as:
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">recurrence_functor_ik</span> <span class="special">=</span> <span class="special">[&amp;](</span><span class="keyword">int</span> <span class="identifier">n</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="number">1.0</span><span class="special">,</span> <span class="special">-</span><span class="number">2</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">v</span> <span class="special">+</span> <span class="identifier">n</span><span class="special">)</span> <span class="special">/</span> <span class="identifier">x</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">);</span> <span class="special">};</span>
</pre>
<p>
The tools are then as follows:
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Recurrence</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="identifier">T</span> <span class="identifier">function_ratio_from_backwards_recurrence</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Recurrence</span><span class="special">&amp;</span> <span class="identifier">r</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">factor</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&amp;</span> <span class="identifier">max_iter</span><span class="special">);</span>
</pre>
<p>
Given a functor <code class="computeroutput"><span class="identifier">r</span></code> which encodes
the recurrence relation for function <code class="computeroutput"><span class="identifier">F</span></code>
at some location <span class="emphasis"><em>n</em></span>, then returns the ratio:
</p>
<p>
<span class="inlinemediaobject"><object type="image/svg+xml" data="../../../equations/three_term_recurrence_backwards_ratio.svg" width="63" height="20"></object></span>
</p>
<p>
This calculation is stable only if recurrence is stable in the backwards
direction. Further the ratio calculated is for the dominant solution (in
the backwards direction) of the recurrence relation, if there are multiple
solutions, then there is no guarantee that this will find the one you want
or expect.
</p>
<p>
Argument <span class="emphasis"><em>factor</em></span> is the tolerance required for convergence
of the continued fraction associated with the recurrence relation, and should
be no smaller than machine epsilon. Argument <span class="emphasis"><em>max_iter</em></span>
sets the maximum number of permitted iterations in the associated continued
fraction.
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Recurrence</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="identifier">T</span> <span class="identifier">function_ratio_from_forwards_recurrence</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Recurrence</span><span class="special">&amp;</span> <span class="identifier">r</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">factor</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&amp;</span> <span class="identifier">max_iter</span><span class="special">);</span>
</pre>
<p>
Given a functor <code class="computeroutput"><span class="identifier">r</span></code> which encodes
the recurrence relation for function F at some location <span class="emphasis"><em>n</em></span>,
then returns the ratio:
</p>
<p>
<span class="inlinemediaobject"><object type="image/svg+xml" data="../../../equations/three_term_recurrence_forwards_ratio.svg" width="63" height="20"></object></span>
</p>
<p>
This calculation is stable only if recurrence is stable in the forwards direction.
Further the ratio calculated is for the dominant solution (in the forwards
direction) of the recurrence relation, if there are multiple solutions, then
there is no guarantee that this will find the one you want or expect.
</p>
<p>
Argument <span class="emphasis"><em>factor</em></span> is the tolerance required for convergence
of the continued fraction associated with the recurrence relation, and should
be no smaller than machine epsilon. Argument <span class="emphasis"><em>max_iter</em></span>
sets the maximum number of permitted iterations in the associated continued
fraction.
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">NextCoefs</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="identifier">T</span> <span class="identifier">apply_recurrence_relation_forward</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">NextCoefs</span><span class="special">&amp;</span> <span class="identifier">get_coefs</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="identifier">number_of_steps</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">second</span><span class="special">,</span> <span class="keyword">long</span> <span class="keyword">long</span><span class="special">*</span> <span class="identifier">log_scaling</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">T</span><span class="special">*</span> <span class="identifier">previous</span> <span class="special">=</span> <span class="number">0</span><span class="special">);</span>
</pre>
<p>
Applies a recurrence relation in a stable forward direction, starting with
the values F<sub>n-1</sub> and F<sub>n</sub>.
</p>
<div class="variablelist">
<p class="title"><b></b></p>
<dl class="variablelist">
<dt><span class="term">get_coefs</span></dt>
<dd><p>
Functor that returns the coefficients of the recurrence relation. The
coefficients should be centered on position <span class="emphasis"><em>second</em></span>.
</p></dd>
<dt><span class="term">number_of_steps</span></dt>
<dd><p>
The number of steps to apply the recurrence relation onwards from
<span class="emphasis"><em>second</em></span>.
</p></dd>
<dt><span class="term">first</span></dt>
<dd><p>
The value of F<sub>n-1</sub>
</p></dd>
<dt><span class="term">second</span></dt>
<dd><p>
The value of F<sub>n</sub>
</p></dd>
<dt><span class="term">log_scaling</span></dt>
<dd><p>
When provided, the recurrence relations may be rescaled internally
to avoid over/underflow issues. The result should be multiplied by
<code class="computeroutput"><span class="identifier">exp</span><span class="special">(*</span><span class="identifier">log_scaling</span><span class="special">)</span></code>
to get the true value of the result.
</p></dd>
<dt><span class="term">previous</span></dt>
<dd><p>
When provided, is set to the value of F<sub>n + number_of_steps - 1</sub>
</p></dd>
</dl>
</div>
<p>
Returns F<sub>n + number_of_steps</sub>.
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">NextCoefs</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="identifier">T</span> <span class="identifier">apply_recurrence_relation_backward</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">NextCoefs</span><span class="special">&amp;</span> <span class="identifier">get_coefs</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="identifier">number_of_steps</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">second</span><span class="special">,</span> <span class="keyword">long</span> <span class="keyword">long</span><span class="special">*</span> <span class="identifier">log_scaling</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">T</span><span class="special">*</span> <span class="identifier">previous</span> <span class="special">=</span> <span class="number">0</span><span class="special">);</span>
</pre>
<p>
Applies a recurrence relation in a stable backward direction, starting with
the values F<sub>n+1</sub> and F<sub>n</sub>.
</p>
<div class="variablelist">
<p class="title"><b></b></p>
<dl class="variablelist">
<dt><span class="term">get_coefs</span></dt>
<dd><p>
Functor that returns the coefficients of the recurrence relation. The
coefficients should be centered on position <span class="emphasis"><em>second</em></span>.
</p></dd>
<dt><span class="term">number_of_steps</span></dt>
<dd><p>
The number of steps to apply the recurrence relation backwards from
<span class="emphasis"><em>second</em></span>.
</p></dd>
<dt><span class="term">first</span></dt>
<dd><p>
The value of F<sub>n+1</sub>
</p></dd>
<dt><span class="term">second</span></dt>
<dd><p>
The value of F<sub>n</sub>
</p></dd>
<dt><span class="term">log_scaling</span></dt>
<dd><p>
When provided, the recurrence relations may be rescaled internally
to avoid over/underflow issues. The result should be multiplied by
<code class="computeroutput"><span class="identifier">exp</span><span class="special">(*</span><span class="identifier">log_scaling</span><span class="special">)</span></code>
to get the true value of the result.
</p></dd>
<dt><span class="term">previous</span></dt>
<dd><p>
When provided, is set to the value of F<sub>n - number_of_steps + 1</sub>
</p></dd>
</dl>
</div>
<p>
Returns F<sub>n - number_of_steps</sub>.
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Recurrence</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">forward_recurrence_iterator</span>
<span class="special">{</span>
<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_reference</span><span class="special">&lt;</span><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">declval</span><span class="special">&lt;</span><span class="identifier">Recurrence</span><span class="special">&amp;&gt;()(</span><span class="number">0</span><span class="special">)))&gt;::</span><span class="identifier">type</span> <span class="identifier">value_type</span><span class="special">;</span>
<span class="identifier">forward_recurrence_iterator</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Recurrence</span><span class="special">&amp;</span> <span class="identifier">r</span><span class="special">,</span> <span class="identifier">value_type</span> <span class="identifier">f_n_minus_1</span><span class="special">,</span> <span class="identifier">value_type</span> <span class="identifier">f_n</span><span class="special">);</span>
<span class="identifier">forward_recurrence_iterator</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Recurrence</span><span class="special">&amp;</span> <span class="identifier">r</span><span class="special">,</span> <span class="identifier">value_type</span> <span class="identifier">f_n</span><span class="special">);</span>
<span class="comment">/* Operators omitted for clarity */</span>
<span class="special">};</span>
</pre>
<p>
Type <code class="computeroutput"><span class="identifier">forward_recurrence_iterator</span></code>
defines a forward-iterator for a recurrence relation stable in the forward
direction. The constructors take the recurrence relation, plus either one
or two values: if only one value is provided, then the second is computed
by using the recurrence relation to calculate the function ratio.
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Recurrence</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">backward_recurrence_iterator</span>
<span class="special">{</span>
<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_reference</span><span class="special">&lt;</span><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">declval</span><span class="special">&lt;</span><span class="identifier">Recurrence</span><span class="special">&amp;&gt;()(</span><span class="number">0</span><span class="special">)))&gt;::</span><span class="identifier">type</span> <span class="identifier">value_type</span><span class="special">;</span>
<span class="identifier">backward_recurrence_iterator</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Recurrence</span><span class="special">&amp;</span> <span class="identifier">r</span><span class="special">,</span> <span class="identifier">value_type</span> <span class="identifier">f_n_plus_1</span><span class="special">,</span> <span class="identifier">value_type</span> <span class="identifier">f_n</span><span class="special">);</span>
<span class="identifier">backward_recurrence_iterator</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Recurrence</span><span class="special">&amp;</span> <span class="identifier">r</span><span class="special">,</span> <span class="identifier">value_type</span> <span class="identifier">f_n</span><span class="special">);</span>
<span class="comment">/* Operators omitted for clarity */</span>
<span class="special">};</span>
</pre>
<p>
Type <code class="computeroutput"><span class="identifier">backward_recurrence_iterator</span></code>
defines a forward-iterator for a recurrence relation stable in the backward
direction. The constructors take the recurrence relation, plus either one
or two values: if only one value is provided, then the second is computed
by using the recurrence relation to calculate the function ratio.
</p>
<p>
Note that <span class="emphasis"><em>incrementing</em></span> this iterator moves the value
returned successively to F<sub>n-1</sub>, F<sub>n-2</sub> etc.
</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="engel_expansion.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="cohen_acceleration.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -1,13 +1,13 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Series 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.6.0">
<link rel="home" href="../../index.html" title="Math Toolkit 3.0.0">
<link rel="up" href="../internals.html" title="Internal tools">
<link rel="prev" href="../internals.html" title="Internal tools">
<link rel="next" href="cf.html" title="Continued Fraction Evaluation">
<link rel="next" href="agm.html" title="Arithmetic-Geometric Mean">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
@@ -20,7 +20,7 @@
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../internals.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="cf.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
<a accesskey="p" href="../internals.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="agm.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
@@ -79,8 +79,9 @@
<p>
The second argument is the precision required, summation will stop when the
next term is less than <span class="emphasis"><em>tolerance</em></span> times the result. The
deprecated versions of sum_series take an integer number of bits here - internally
they just convert this to a tolerance and forward the call.
deprecated versions of <code class="computeroutput"><span class="identifier">sum_series</span></code>
take an integer number of bits here - internally they just convert this to
a tolerance and forward the call.
</p>
<p>
The third argument <span class="emphasis"><em>max_terms</em></span> sets an upper limit on
@@ -122,15 +123,19 @@
</p>
<h5>
<a name="math_toolkit.internals.series_evaluation.h2"></a>
<span class="phrase"><a name="math_toolkit.internals.series_evaluation.example"></a></span><a class="link" href="series_evaluation.html#math_toolkit.internals.series_evaluation.example">Example</a>
<span class="phrase"><a name="math_toolkit.internals.series_evaluation.examples"></a></span><a class="link" href="series_evaluation.html#math_toolkit.internals.series_evaluation.examples">Examples</a>
</h5>
<p>
These examples are all in <a href="../../../../example/series.cpp" target="_top">../../example/series.cpp</a>
</p>
<p>
Let's suppose we want to implement <span class="emphasis"><em>log(1+x)</em></span> via its
infinite series,
</p>
<p>
<span class="inlinemediaobject"><img src="../../../equations/log1pseries.svg"></span>
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="inlinemediaobject"><img src="../../../equations/log1pseries.svg"></span>
</p></blockquote></div>
<p>
We begin by writing a small function object to return successive terms of
the series:
@@ -142,13 +147,13 @@
<span class="keyword">typedef</span> <span class="identifier">T</span> <span class="identifier">result_type</span><span class="special">;</span>
<span class="identifier">log1p_series</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="identifier">k</span><span class="special">(</span><span class="number">0</span><span class="special">),</span> <span class="identifier">m_mult</span><span class="special">(-</span><span class="identifier">x</span><span class="special">),</span> <span class="identifier">m_prod</span><span class="special">(-</span><span class="number">1</span><span class="special">){}</span>
<span class="special">:</span> <span class="identifier">k</span><span class="special">(</span><span class="number">0</span><span class="special">),</span> <span class="identifier">m_mult</span><span class="special">(-</span><span class="identifier">x</span><span class="special">),</span> <span class="identifier">m_prod</span><span class="special">(-</span><span class="number">1</span><span class="special">)</span> <span class="special">{}</span>
<span class="identifier">T</span> <span class="keyword">operator</span><span class="special">()()</span>
<span class="special">{</span>
<span class="comment">// This is the function operator invoked by the summation</span>
<span class="comment">// algorithm, the first call to this operator should return</span>
<span class="comment">// the first term of the series, the second call the second </span>
<span class="comment">// the first term of the series, the second call the second</span>
<span class="comment">// term and so on.</span>
<span class="identifier">m_prod</span> <span class="special">*=</span> <span class="identifier">m_mult</span><span class="special">;</span>
<span class="keyword">return</span> <span class="identifier">m_prod</span> <span class="special">/</span> <span class="special">++</span><span class="identifier">k</span><span class="special">;</span>
@@ -167,24 +172,75 @@
<span class="identifier">T</span> <span class="identifier">log1p</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">// We really should add some error checking on x here!</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">fabs</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">&lt;</span> <span class="number">1</span><span class="special">);</span>
<span class="identifier">BOOST_ASSERT</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">fabs</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">&lt;</span> <span class="number">1</span><span class="special">);</span>
<span class="comment">// Construct the series functor:</span>
<span class="identifier">log1p_series</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">s</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
<span class="comment">// Set a limit on how many iterations we permit:</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span> <span class="identifier">max_iter</span> <span class="special">=</span> <span class="number">1000</span><span class="special">;</span>
<span class="comment">// Add it up, with enough precision for full machine precision:</span>
<span class="keyword">return</span> <span class="identifier">tools</span><span class="special">::</span><span class="identifier">sum_series</span><span class="special">(</span><span class="identifier">s</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">epsilon</span><span class="special">(),</span> <span class="identifier">max_iter</span><span class="special">);</span>
<span class="keyword">return</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">sum_series</span><span class="special">(</span><span class="identifier">s</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">epsilon</span><span class="special">(),</span> <span class="identifier">max_iter</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
We can almost use the code above for complex numbers as well - unfortunately
we need a slightly different definition for epsilon, and within the functor,
mixed complex and integer arithmetic is sadly not supported (as of C++17),
so we need to cast out integers to floats:
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">log1p_series</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&gt;</span>
<span class="special">{</span>
<span class="comment">// we must define a result_type typedef:</span>
<span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">result_type</span><span class="special">;</span>
<span class="identifier">log1p_series</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">x</span><span class="special">)</span>
<span class="special">:</span> <span class="identifier">k</span><span class="special">(</span><span class="number">0</span><span class="special">),</span> <span class="identifier">m_mult</span><span class="special">(-</span><span class="identifier">x</span><span class="special">),</span> <span class="identifier">m_prod</span><span class="special">(-</span><span class="number">1</span><span class="special">)</span> <span class="special">{}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span><span class="special">()()</span>
<span class="special">{</span>
<span class="comment">// This is the function operator invoked by the summation</span>
<span class="comment">// algorithm, the first call to this operator should return</span>
<span class="comment">// the first term of the series, the second call the second</span>
<span class="comment">// term and so on.</span>
<span class="identifier">m_prod</span> <span class="special">*=</span> <span class="identifier">m_mult</span><span class="special">;</span>
<span class="keyword">return</span> <span class="identifier">m_prod</span> <span class="special">/</span> <span class="identifier">T</span><span class="special">(++</span><span class="identifier">k</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="keyword">int</span> <span class="identifier">k</span><span class="special">;</span>
<span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">m_mult</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">m_prod</span><span class="special">;</span>
<span class="special">};</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">log1p</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">x</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// We really should add some error checking on x here!</span>
<span class="identifier">BOOST_ASSERT</span><span class="special">(</span><span class="identifier">abs</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">&lt;</span> <span class="number">1</span><span class="special">);</span>
<span class="comment">// Construct the series functor:</span>
<span class="identifier">log1p_series</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">s</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
<span class="comment">// Set a limit on how many iterations we permit:</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span> <span class="identifier">max_iter</span> <span class="special">=</span> <span class="number">1000</span><span class="special">;</span>
<span class="comment">// Add it up, with enough precision for full machine precision:</span>
<span class="keyword">return</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">sum_series</span><span class="special">(</span><span class="identifier">s</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">epsilon</span><span class="special">()),</span> <span class="identifier">max_iter</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
Of course with a few traits classes and a bit of meta-programming we could
fold these two implementations into one, but that's beyond the scope of these
examples.
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2006-2010, 2012-2014, 2017 Nikhar
Agrawal, Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos,
Hubert Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan R&#229;de, Gautam
Sewani, Benjamin Sobotta, Nicholas Thompson, Thijs van den Berg, Daryle Walker
and Xiaogang Zhang<p>
<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>
@@ -192,7 +248,7 @@
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../internals.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="cf.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
<a accesskey="p" href="../internals.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="agm.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,122 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Simple Continued Fractions</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="../internals.html" title="Internal tools">
<link rel="prev" href="cf.html" title="Continued Fraction Evaluation">
<link rel="next" href="centered_continued_fraction.html" title="Centered Continued Fractions">
</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="cf.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="centered_continued_fraction.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.internals.simple_continued_fraction"></a><a class="link" href="simple_continued_fraction.html" title="Simple Continued Fractions">Simple
Continued Fractions</a>
</h3></div></div></div>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">tools</span><span class="special">/</span><span class="identifier">simple_continued_fraction</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</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">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Real</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Z</span> <span class="special">=</span> <span class="identifier">int64_t</span><span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">simple_continued_fraction</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="identifier">simple_continued_fraction</span><span class="special">(</span><span class="identifier">Real</span> <span class="identifier">x</span><span class="special">);</span>
<span class="identifier">Real</span> <span class="identifier">khinchin_geometric_mean</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">Real</span> <span class="identifier">khinchin_harmonic_mean</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Z_</span><span class="special">&gt;</span>
<span class="keyword">friend</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">&lt;&lt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="identifier">out</span><span class="special">,</span> <span class="identifier">simple_continued_fraction</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">&gt;&amp;</span> <span class="identifier">scf</span><span class="special">);</span>
<span class="special">};</span>
<span class="special">}</span>
</pre>
<p>
The <code class="computeroutput"><span class="identifier">simple_continued_fraction</span></code>
class provided by Boost affords the ability to convert a floating point number
into a simple continued fraction. In addition, we can answer a few questions
about the number in question using this representation.
</p>
<p>
Here's a minimal working example:
</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">constants</span><span class="special">::</span><span class="identifier">pi</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">simple_continued_fraction</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">cfrac</span> <span class="special">=</span> <span class="identifier">simple_continued_fraction</span><span class="special">(</span><span class="identifier">pi</span><span class="special">&lt;</span><span class="keyword">long</span> <span class="keyword">double</span><span class="special">&gt;());</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"π ≈ "</span> <span class="special">&lt;&lt;</span> <span class="identifier">cfrac</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
<span class="comment">// Prints:</span>
<span class="comment">// π ≈ [3; 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2]</span>
</pre>
<p>
The class computes partial denominators while simultaneously computing convergents
with the modified Lentz's algorithm. Once a convergent is within a few ulps
of the input value, the computation stops.
</p>
<p>
Note that every floating point number is a rational number, and this exact
rational can be exactly converted to a finite continued fraction. This is
perfectly sensible behavior, but we do not do it here. This is because when
examining known values like π, it creates a large number of incorrect partial
denominators, even if every bit of the binary representation is correct.
</p>
<p>
It may be the case the a few incorrect partial convergents is harmless, but
we compute continued fractions because we would like to do something with
them. One sensible thing to do it to ask whether the number is in some sense
"random"; a question that can be partially answered by computing
the Khinchin geometric mean
</p>
<p>
<span class="inlinemediaobject"><object type="image/svg+xml" data="../../../equations/khinchin_geometric.svg" width="173" height="22"></object></span>
</p>
<p>
and Khinchin harmonic mean
</p>
<p>
<span class="inlinemediaobject"><object type="image/svg+xml" data="../../../equations/khinchin_harmonic.svg" width="153" height="40"></object></span>
</p>
<p>
If these approach Khinchin's constant <span class="emphasis"><em>K</em></span><sub>0</sub> and <span class="emphasis"><em>K</em></span><sub>-1</sub> as
the number of partial denominators goes to infinity, then our number is "uninteresting"
with respect to the characterization. These violations are washed out if
too many incorrect partial denominators are included in the expansion.
</p>
<p>
Note: The convergence of these means to the Khinchin limit is exceedingly
slow; we've used 30,000 decimal digits of π and only found two digits of
agreement with <span class="emphasis"><em>K</em></span><sub>0</sub>. However, clear violations of are
obvious, such as the continued fraction expansion of √2, whose Khinchin
geometric mean is precisely 2.
</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="cf.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="centered_continued_fraction.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -1,13 +1,13 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Graphing, Profiling, and Generating Test Data for Special 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.6.0">
<link rel="home" href="../../index.html" title="Math Toolkit 3.0.0">
<link rel="up" href="../internals.html" title="Internal tools">
<link rel="prev" href="error_test.html" title="Relative Error and Testing">
<link rel="next" href="../../using_udt.html" title="Chapter&#160;17.&#160;Use with User-Defined Floating-Point Types - Boost.Multiprecision and others">
<link rel="next" href="../../using_udt.html" title="Chapter 20. Use with User-Defined Floating-Point Types - Boost.Multiprecision and others">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
@@ -220,9 +220,10 @@
<p>
Which, when plotted, results in:
</p>
<p>
<span class="inlinemediaobject"><img src="../../../graphs/lgamma.svg" align="middle"></span>
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="inlinemediaobject"><img src="../../../graphs/lgamma.svg" align="middle"></span>
</p></blockquote></div>
<h6>
<a name="math_toolkit.internals.test_data.h3"></a>
<span class="phrase"><a name="math_toolkit.internals.test_data.example_2_creating_test_data"></a></span><a class="link" href="test_data.html#math_toolkit.internals.test_data.example_2_creating_test_data">Example
@@ -441,13 +442,13 @@
<span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">T</span> <span class="identifier">val</span><span class="special">)</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">// estimate the true value, using arbitary precision</span>
<span class="comment">// estimate the true value, using arbitrary precision</span>
<span class="comment">// arithmetic and NTL::RR:</span>
<span class="identifier">NTL</span><span class="special">::</span><span class="identifier">RR</span> <span class="identifier">rval</span><span class="special">(</span><span class="identifier">val</span><span class="special">);</span>
<span class="identifier">upper_incomplete_gamma_fract</span><span class="special">&lt;</span><span class="identifier">NTL</span><span class="special">::</span><span class="identifier">RR</span><span class="special">&gt;</span> <span class="identifier">f1</span><span class="special">(</span><span class="identifier">rval</span><span class="special">,</span> <span class="identifier">rval</span><span class="special">);</span>
<span class="identifier">NTL</span><span class="special">::</span><span class="identifier">RR</span> <span class="identifier">true_val</span> <span class="special">=</span> <span class="identifier">continued_fraction_a</span><span class="special">(</span><span class="identifier">f1</span><span class="special">,</span> <span class="number">1000</span><span class="special">);</span>
<span class="comment">//</span>
<span class="comment">// Now get the aproximation at double precision, along with the number of</span>
<span class="comment">// Now get the approximation at double precision, along with the number of</span>
<span class="comment">// iterations required:</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span> <span class="identifier">iters</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&gt;::</span><span class="identifier">max</span><span class="special">();</span>
<span class="identifier">upper_incomplete_gamma_fract</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">f2</span><span class="special">(</span><span class="identifier">val</span><span class="special">,</span> <span class="identifier">val</span><span class="special">);</span>
@@ -492,7 +493,7 @@
</pre>
<p>
So it's pretty clear that this fraction shouldn't be used for small values
of a and z.
of <span class="emphasis"><em>a</em></span> and <span class="emphasis"><em>z</em></span>.
</p>
<h5>
<a name="math_toolkit.internals.test_data.h5"></a>
@@ -546,11 +547,11 @@
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2006-2010, 2012-2014, 2017 Nikhar
Agrawal, Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos,
Hubert Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan R&#229;de, Gautam
Sewani, Benjamin Sobotta, Nicholas Thompson, Thijs van den Berg, Daryle Walker
and Xiaogang Zhang<p>
<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>

View File

@@ -1,12 +1,12 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Tuples</title>
<link rel="stylesheet" href="../../math.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../index.html" title="Math Toolkit 2.6.0">
<link rel="home" href="../../index.html" title="Math Toolkit 3.0.0">
<link rel="up" href="../internals.html" title="Internal tools">
<link rel="prev" href="cf.html" title="Continued Fraction Evaluation">
<link rel="prev" href="cohen_acceleration.html" title="Cohen Acceleration">
<link rel="next" href="minimax.html" title="Minimax Approximations and the Remez Algorithm">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
@@ -20,7 +20,7 @@
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cf.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="minimax.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
<a accesskey="p" href="cohen_acceleration.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="minimax.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
@@ -68,11 +68,11 @@
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2006-2010, 2012-2014, 2017 Nikhar
Agrawal, Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos,
Hubert Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan R&#229;de, Gautam
Sewani, Benjamin Sobotta, Nicholas Thompson, Thijs van den Berg, Daryle Walker
and Xiaogang Zhang<p>
<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>
@@ -80,7 +80,7 @@
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cf.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="minimax.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
<a accesskey="p" href="cohen_acceleration.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../internals.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="minimax.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>