[DEV] add v1.66.0

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

View File

@@ -0,0 +1,282 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<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="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">
</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="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.cf"></a><a class="link" href="cf.html" title="Continued Fraction Evaluation">Continued Fraction Evaluation</a>
</h3></div></div></div>
<h5>
<a name="math_toolkit.internals.cf.h0"></a>
<span class="phrase"><a name="math_toolkit.internals.cf.synopsis"></a></span><a class="link" href="cf.html#math_toolkit.internals.cf.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">fraction</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">Gen</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">detail</span><span class="special">::</span><span class="identifier">fraction_traits</span><span class="special">&lt;</span><span class="identifier">Gen</span><span class="special">&gt;::</span><span class="identifier">result_type</span>
<span class="identifier">continued_fraction_b</span><span class="special">(</span><span class="identifier">Gen</span><span class="special">&amp;</span> <span class="identifier">g</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">U</span><span class="special">&amp;</span> <span class="identifier">tolerance</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_terms</span><span class="special">)</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Gen</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">detail</span><span class="special">::</span><span class="identifier">fraction_traits</span><span class="special">&lt;</span><span class="identifier">Gen</span><span class="special">&gt;::</span><span class="identifier">result_type</span>
<span class="identifier">continued_fraction_b</span><span class="special">(</span><span class="identifier">Gen</span><span class="special">&amp;</span> <span class="identifier">g</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">U</span><span class="special">&amp;</span> <span class="identifier">tolerance</span><span class="special">)</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Gen</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">detail</span><span class="special">::</span><span class="identifier">fraction_traits</span><span class="special">&lt;</span><span class="identifier">Gen</span><span class="special">&gt;::</span><span class="identifier">result_type</span>
<span class="identifier">continued_fraction_a</span><span class="special">(</span><span class="identifier">Gen</span><span class="special">&amp;</span> <span class="identifier">g</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">U</span><span class="special">&amp;</span> <span class="identifier">tolerance</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_terms</span><span class="special">)</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Gen</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">detail</span><span class="special">::</span><span class="identifier">fraction_traits</span><span class="special">&lt;</span><span class="identifier">Gen</span><span class="special">&gt;::</span><span class="identifier">result_type</span>
<span class="identifier">continued_fraction_a</span><span class="special">(</span><span class="identifier">Gen</span><span class="special">&amp;</span> <span class="identifier">g</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">U</span><span class="special">&amp;</span> <span class="identifier">tolerance</span><span class="special">)</span>
<span class="comment">//</span>
<span class="comment">// These interfaces are present for legacy reasons, and are now deprecated:</span>
<span class="comment">//</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Gen</span><span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">detail</span><span class="special">::</span><span class="identifier">fraction_traits</span><span class="special">&lt;</span><span class="identifier">Gen</span><span class="special">&gt;::</span><span class="identifier">result_type</span>
<span class="identifier">continued_fraction_b</span><span class="special">(</span><span class="identifier">Gen</span><span class="special">&amp;</span> <span class="identifier">g</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">bits</span><span class="special">);</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Gen</span><span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">detail</span><span class="special">::</span><span class="identifier">fraction_traits</span><span class="special">&lt;</span><span class="identifier">Gen</span><span class="special">&gt;::</span><span class="identifier">result_type</span>
<span class="identifier">continued_fraction_b</span><span class="special">(</span><span class="identifier">Gen</span><span class="special">&amp;</span> <span class="identifier">g</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">bits</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&amp;</span> <span class="identifier">max_terms</span><span class="special">);</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Gen</span><span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">detail</span><span class="special">::</span><span class="identifier">fraction_traits</span><span class="special">&lt;</span><span class="identifier">Gen</span><span class="special">&gt;::</span><span class="identifier">result_type</span>
<span class="identifier">continued_fraction_a</span><span class="special">(</span><span class="identifier">Gen</span><span class="special">&amp;</span> <span class="identifier">g</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">bits</span><span class="special">);</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Gen</span><span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">detail</span><span class="special">::</span><span class="identifier">fraction_traits</span><span class="special">&lt;</span><span class="identifier">Gen</span><span class="special">&gt;::</span><span class="identifier">result_type</span>
<span class="identifier">continued_fraction_a</span><span class="special">(</span><span class="identifier">Gen</span><span class="special">&amp;</span> <span class="identifier">g</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">bits</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&amp;</span> <span class="identifier">max_terms</span><span class="special">);</span>
<span class="special">}}}</span> <span class="comment">// namespaces</span>
</pre>
<h5>
<a name="math_toolkit.internals.cf.h1"></a>
<span class="phrase"><a name="math_toolkit.internals.cf.description"></a></span><a class="link" href="cf.html#math_toolkit.internals.cf.description">Description</a>
</h5>
<p>
<a href="http://en.wikipedia.org/wiki/Continued_fraction" target="_top">Continued fractions
are a common method of approximation. </a> These functions all evaluate
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>
<p>
and those with a "_b" suffix evaluate the fraction:
</p>
<p>
<span class="inlinemediaobject"><img src="../../../equations/fraction1.svg"></span>
</p>
<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>
value returned by the generator is discarded. Further, often the first <span class="emphasis"><em>a</em></span>
and <span class="emphasis"><em>b</em></span> values in a continued fraction have different
defining equations to the remaining terms, which may make the "_a"
suffixed form more appropriate.
</p>
<p>
The generator type should be a function object which supports the following
operations:
</p>
<div class="informaltable"><table class="table">
<colgroup>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
Expression
</p>
</th>
<th>
<p>
Description
</p>
</th>
</tr></thead>
<tbody>
<tr>
<td>
<p>
Gen::result_type
</p>
</td>
<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.
</p>
</td>
</tr>
<tr>
<td>
<p>
g()
</p>
</td>
<td>
<p>
Returns an object of type Gen::result_type.
</p>
<p>
Each time this operator is called then the next pair of <span class="emphasis"><em>a</em></span>
and <span class="emphasis"><em>b</em></span> values is returned. Or, if result_type
is an arithmetic type, then the next <span class="emphasis"><em>b</em></span> value
is returned and all the <span class="emphasis"><em>a</em></span> values are assumed
to 1.
</p>
</td>
</tr>
</tbody>
</table></div>
<p>
In all the continued fraction evaluation functions the <span class="emphasis"><em>tolerance</em></span>
parameter is the precision desired in the result, evaluation of the fraction
will continue until the last term evaluated leaves the relative error in
the result less than <span class="emphasis"><em>tolerance</em></span>. The deprecated interfaces
take a number of digits precision here, internally they just convert this
to a tolerance and forward call.
</p>
<p>
If the optional <span class="emphasis"><em>max_terms</em></span> parameter is specified then
no more than <span class="emphasis"><em>max_terms</em></span> calls to the generator will be
made, and on output, <span class="emphasis"><em>max_terms</em></span> will be set to actual
number of calls made. This facility is particularly useful when profiling
a continued fraction for convergence.
</p>
<h5>
<a name="math_toolkit.internals.cf.h2"></a>
<span class="phrase"><a name="math_toolkit.internals.cf.implementation"></a></span><a class="link" href="cf.html#math_toolkit.internals.cf.implementation">Implementation</a>
</h5>
<p>
Internally these algorithms all use the modified Lentz algorithm: refer to
Numeric Recipes in C++, W. H. Press et all, chapter 5, (especially 5.2 Evaluation
of continued fractions, p 175 - 179) for more information, also Lentz, W.J.
1976, Applied Optics, vol. 15, pp. 668-671.
</p>
<h5>
<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>
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>
<p>
We begin by defining a generator 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">struct</span> <span class="identifier">golden_ratio_fraction</span>
<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="special">{</span>
<span class="keyword">return</span> <span class="number">1</span><span class="special">;</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
<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>
<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>
</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>
<p>
So its generator object would look like:
</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">tan_fraction</span>
<span class="special">{</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="identifier">T</span> <span class="identifier">a</span><span class="special">,</span> <span class="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="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="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>
<span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
Notice that if the continuant is subtracted from the <span class="emphasis"><em>b</em></span>
terms, as is the case here, then all the <span class="emphasis"><em>a</em></span> terms returned
by the generator will be negative. The tangent function can now be evaluated
using:
</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="identifier">T</span> <span class="identifier">tan</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">a</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">tan_fraction</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">fract</span><span class="special">(</span><span class="identifier">a</span><span class="special">);</span>
<span class="keyword">return</span> <span class="identifier">a</span> <span class="special">/</span> <span class="identifier">continued_fraction_b</span><span class="special">(</span><span class="identifier">fract</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">epsilon</span><span class="special">());</span>
<span class="special">}</span>
</pre>
<p>
Notice that this time we're using the "_b" suffixed version to
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>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2006-2010, 2012-2014, 2017 Nikhar
Agrawal, Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos,
Hubert Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan R&#229;de, Gautam
Sewani, Benjamin Sobotta, Nicholas Thompson, Thijs van den Berg, Daryle Walker
and Xiaogang Zhang<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="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>
</div>
</body>
</html>

View File

@@ -0,0 +1,238 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<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="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">
</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="minimax.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="test_data.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.error_test"></a><a class="link" href="error_test.html" title="Relative Error and Testing">Relative Error and
Testing</a>
</h3></div></div></div>
<h5>
<a name="math_toolkit.internals.error_test.h0"></a>
<span class="phrase"><a name="math_toolkit.internals.error_test.synopsis"></a></span><a class="link" href="error_test.html#math_toolkit.internals.error_test.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">test</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</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
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>
</table></div>
<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="identifier">T</span> <span class="identifier">relative_error</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">b</span><span class="special">);</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">F1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">F2</span><span class="special">&gt;</span>
<span class="identifier">test_result</span><span class="special">&lt;</span><span class="identifier">see</span><span class="special">-</span><span class="identifier">below</span><span class="special">&gt;</span> <span class="identifier">test</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">F1</span> <span class="identifier">test_func</span><span class="special">,</span> <span class="identifier">F2</span> <span class="identifier">expect_func</span><span class="special">);</span>
</pre>
<h5>
<a name="math_toolkit.internals.error_test.h1"></a>
<span class="phrase"><a name="math_toolkit.internals.error_test.description"></a></span><a class="link" href="error_test.html#math_toolkit.internals.error_test.description">Description</a>
</h5>
<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="identifier">T</span> <span class="identifier">relative_error</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">v</span><span class="special">);</span>
</pre>
<p>
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>
<p>
In addition the value returned is zero if:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Both <span class="emphasis"><em>a</em></span> and <span class="emphasis"><em>v</em></span> are infinite.
</li>
<li class="listitem">
Both <span class="emphasis"><em>a</em></span> and <span class="emphasis"><em>v</em></span> are denormalised
numbers or zero.
</li>
</ul></div>
<p>
Otherwise if only one of <span class="emphasis"><em>a</em></span> and <span class="emphasis"><em>v</em></span>
is zero then the value returned is 1.
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">F1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">F2</span><span class="special">&gt;</span>
<span class="identifier">test_result</span><span class="special">&lt;</span><span class="identifier">see</span><span class="special">-</span><span class="identifier">below</span><span class="special">&gt;</span> <span class="identifier">test</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">F1</span> <span class="identifier">test_func</span><span class="special">,</span> <span class="identifier">F2</span> <span class="identifier">expect_func</span><span class="special">);</span>
</pre>
<p>
This function is used for testing a function against tabulated test data.
</p>
<p>
The return type contains statistical data on the relative errors (max, mean,
variance, and the number of test cases etc), as well as the row of test data
that caused the largest relative error. Public members of type test_result
are:
</p>
<div class="variablelist">
<p class="title"><b></b></p>
<dl class="variablelist">
<dt><span class="term"><code class="computeroutput"><span class="keyword">unsigned</span> <span class="identifier">worst</span><span class="special">()</span><span class="keyword">const</span><span class="special">;</span></code></span></dt>
<dd><p>
Returns the row at which the worst error occurred.
</p></dd>
<dt><span class="term"><code class="computeroutput"><span class="identifier">T</span> <span class="identifier">min</span><span class="special">()</span><span class="keyword">const</span><span class="special">;</span></code></span></dt>
<dd><p>
Returns the smallest relative error found.
</p></dd>
<dt><span class="term"><code class="computeroutput"><span class="identifier">T</span> <span class="identifier">max</span><span class="special">()</span><span class="keyword">const</span><span class="special">;</span></code></span></dt>
<dd><p>
Returns the largest relative error found.
</p></dd>
<dt><span class="term"><code class="computeroutput"><span class="identifier">T</span> <span class="identifier">mean</span><span class="special">()</span><span class="keyword">const</span><span class="special">;</span></code></span></dt>
<dd><p>
Returns the mean error found.
</p></dd>
<dt><span class="term"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span> <span class="identifier">count</span><span class="special">()</span><span class="keyword">const</span><span class="special">;</span></code></span></dt>
<dd><p>
Returns the number of test cases.
</p></dd>
<dt><span class="term"><code class="computeroutput"><span class="identifier">T</span> <span class="identifier">variance</span><span class="special">()</span><span class="keyword">const</span><span class="special">;</span></code></span></dt>
<dd><p>
Returns the variance of the errors found.
</p></dd>
<dt><span class="term"><code class="computeroutput"><span class="identifier">T</span> <span class="identifier">variance1</span><span class="special">()</span><span class="keyword">const</span><span class="special">;</span></code></span></dt>
<dd><p>
Returns the unbiased variance of the errors found.
</p></dd>
<dt><span class="term"><code class="computeroutput"><span class="identifier">T</span> <span class="identifier">rms</span><span class="special">()</span><span class="keyword">const</span></code></span></dt>
<dd><p>
Returns the Root Mean Square, or quadratic mean of the errors.
</p></dd>
<dt><span class="term"><code class="computeroutput"><span class="identifier">test_result</span><span class="special">&amp;</span>
<span class="keyword">operator</span><span class="special">+=(</span><span class="keyword">const</span> <span class="identifier">test_result</span><span class="special">&amp;</span> <span class="identifier">t</span><span class="special">)</span></code></span></dt>
<dd><p>
Combines two test_result's into a single result.
</p></dd>
</dl>
</div>
<p>
The template parameter of test_result, is the same type as the values in
the two dimensional array passed to function <span class="emphasis"><em>test</em></span>, roughly
that's <code class="computeroutput"><span class="identifier">A</span><span class="special">::</span><span class="identifier">value_type</span><span class="special">::</span><span class="identifier">value_type</span></code>.
</p>
<p>
Parameter <span class="emphasis"><em>a</em></span> is a matrix of test data: and must be a
standard library Sequence type, that contains another Sequence type: typically
it will be a two dimensional instance of <code class="literal">boost::array</code>.
Each row of <span class="emphasis"><em>a</em></span> should contain all the parameters that
are passed to the function under test as well as the expected result.
</p>
<p>
Parameter <span class="emphasis"><em>test_func</em></span> is the function under test, it is
invoked with each row of test data in <span class="emphasis"><em>a</em></span>. Typically type
F1 is created with Boost.Lambda: see the example below.
</p>
<p>
Parameter <span class="emphasis"><em>expect_func</em></span> is a functor that extracts the
expected result from a row of test data in <span class="emphasis"><em>a</em></span>. Typically
type F2 is created with Boost.Lambda: see the example below.
</p>
<p>
If the function under test returns a non-finite value when a finite result
is expected, or if a gross error is found, then a message is sent to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span></code>,
and a call to BOOST_ERROR() made (which means that including this header
requires you use Boost.Test). This is mainly a debugging/development aid
(and a good place for a breakpoint).
</p>
<h5>
<a name="math_toolkit.internals.error_test.h2"></a>
<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.
</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>
<span class="comment">/* big array of test data goes here */</span>
<span class="special">};</span>
</pre>
<p>
Now we can invoke the test function to test tgamma:
</p>
<pre class="programlisting"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">tools</span><span class="special">;</span>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">lambda</span><span class="special">;</span>
<span class="comment">// get a pointer to the function under test:</span>
<span class="identifier">TestType</span> <span class="special">(*</span><span class="identifier">funcp</span><span class="special">)(</span><span class="identifier">TestType</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">tgamma</span><span class="special">;</span>
<span class="comment">// declare something to hold the result:</span>
<span class="identifier">test_result</span><span class="special">&lt;</span><span class="identifier">TestType</span><span class="special">&gt;</span> <span class="identifier">result</span><span class="special">;</span>
<span class="comment">//</span>
<span class="comment">// and test tgamma against data:</span>
<span class="comment">//</span>
<span class="identifier">result</span> <span class="special">=</span> <span class="identifier">test</span><span class="special">(</span>
<span class="identifier">factorials</span><span class="special">,</span>
<span class="identifier">bind</span><span class="special">(</span><span class="identifier">funcp</span><span class="special">,</span> <span class="identifier">ret</span><span class="special">&lt;</span><span class="identifier">TestType</span><span class="special">&gt;(</span><span class="identifier">_1</span><span class="special">[</span><span class="number">0</span><span class="special">])),</span> <span class="comment">// calls tgamma with factorials[row][0]</span>
<span class="identifier">ret</span><span class="special">&lt;</span><span class="identifier">TestType</span><span class="special">&gt;(</span><span class="identifier">_1</span><span class="special">[</span><span class="number">1</span><span class="special">])</span> <span class="comment">// extracts the expected result from factorials[row][1]</span>
<span class="special">);</span>
<span class="comment">//</span>
<span class="comment">// Print out some results:</span>
<span class="comment">//</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 Mean was "</span> <span class="special">&lt;&lt;</span> <span class="identifier">result</span><span class="special">.</span><span class="identifier">mean</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"The worst error was "</span> <span class="special">&lt;&lt;</span> <span class="special">(</span><span class="identifier">result</span><span class="special">.</span><span class="identifier">max</span><span class="special">)()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"The worst error was at row "</span> <span class="special">&lt;&lt;</span> <span class="identifier">result</span><span class="special">.</span><span class="identifier">worst_case</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">//</span>
<span class="comment">// same again with lgamma this time:</span>
<span class="comment">//</span>
<span class="identifier">funcp</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">lgamma</span><span class="special">;</span>
<span class="identifier">result</span> <span class="special">=</span> <span class="identifier">test</span><span class="special">(</span>
<span class="identifier">factorials</span><span class="special">,</span>
<span class="identifier">bind</span><span class="special">(</span><span class="identifier">funcp</span><span class="special">,</span> <span class="identifier">ret</span><span class="special">&lt;</span><span class="identifier">TestType</span><span class="special">&gt;(</span><span class="identifier">_1</span><span class="special">[</span><span class="number">0</span><span class="special">])),</span> <span class="comment">// calls tgamma with factorials[row][0]</span>
<span class="identifier">ret</span><span class="special">&lt;</span><span class="identifier">TestType</span><span class="special">&gt;(</span><span class="identifier">_1</span><span class="special">[</span><span class="number">2</span><span class="special">])</span> <span class="comment">// extracts the expected result from factorials[row][2]</span>
<span class="special">);</span>
<span class="comment">//</span>
<span class="comment">// etc ...</span>
<span class="comment">//</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>
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="minimax.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="test_data.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,284 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<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="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">
</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="tuples.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="error_test.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.minimax"></a><a class="link" href="minimax.html" title="Minimax Approximations and the Remez Algorithm">Minimax Approximations
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.
</p>
<p>
It's worth stressing that developing rational approximations to functions
is often not an easy task, and one to which many books have been devoted.
To use this tool, you will need to have a reasonable grasp of what the Remez
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>.
</p>
<p>
The program consists of two parts:
</p>
<div class="variablelist">
<p class="title"><b></b></p>
<dl class="variablelist">
<dt><span class="term">main.cpp</span></dt>
<dd><p>
Contains the command line parser, and all the calls to the Remez code.
</p></dd>
<dt><span class="term">f.cpp</span></dt>
<dd><p>
Contains the function to approximate.
</p></dd>
</dl>
</div>
<p>
Therefore to use this tool, you must modify f.cpp to return the function
to approximate. The tools supports multiple function approximations within
the same compiled program: each as a separate variant:
</p>
<pre class="programlisting"><span class="identifier">NTL</span><span class="special">::</span><span class="identifier">RR</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">NTL</span><span class="special">::</span><span class="identifier">RR</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">variant</span><span class="special">);</span>
</pre>
<p>
Returns the value of the function <span class="emphasis"><em>variant</em></span> at point
<span class="emphasis"><em>x</em></span>. So if you wish you can just add the function to approximate
as a new variant after the existing examples.
</p>
<p>
In addition to those two files, the program needs to be linked to a <a class="link" href="../high_precision/use_ntl.html" title="Using NTL Library">patched NTL library to compile</a>.
</p>
<p>
Note that the function <span class="emphasis"><em>f</em></span> must return the rational part
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>
<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
the rational approximation part, usually optimised for a low absolute error
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>
and then set the y-offset of the approximation to <span class="emphasis"><em>Y</em></span>
(see command line options below).
</p>
<p>
Many other forms are possible, but in all cases the objective is to split
<span class="emphasis"><em>f(x)</em></span> into a dominant part that you can evaluate easily
using standard math functions, and a smooth and slowly changing rational
approximation part. Refer to your favourite textbook for more examples.
</p>
<p>
Command line options for the program are as follows:
</p>
<div class="variablelist">
<p class="title"><b></b></p>
<dl class="variablelist">
<dt><span class="term">variant N</span></dt>
<dd><p>
Sets the current function variant to N. This allows multiple functions
that are to be approximated to be compiled into the same executable.
Defaults to 0.
</p></dd>
<dt><span class="term">range a b</span></dt>
<dd><p>
Sets the domain for the approximation to the range [a,b], defaults
to [0,1].
</p></dd>
<dt><span class="term">relative</span></dt>
<dd><p>
Sets the Remez code to optimise for relative error. This is the default
at program startup. Note that relative error can only be used if f(x)
has no roots over the range being optimised.
</p></dd>
<dt><span class="term">absolute</span></dt>
<dd><p>
Sets the Remez code to optimise for absolute error.
</p></dd>
<dt><span class="term">pin [true|false]</span></dt>
<dd><p>
"Pins" the code so that the rational approximation passes
through the origin. Obviously only set this to <span class="emphasis"><em>true</em></span>
if R(0) must be zero. This is typically used when trying to preserve
a root at [0,0] while also optimising for relative error.
</p></dd>
<dt><span class="term">order N D</span></dt>
<dd><p>
Sets the order of the approximation to <span class="emphasis"><em>N</em></span> in the
numerator and <span class="emphasis"><em>D</em></span> in the denominator. If <span class="emphasis"><em>D</em></span>
is zero then the result will be a polynomial approximation. There will
be N+D+2 coefficients in total, the first coefficient of the numerator
is zero if <span class="emphasis"><em>pin</em></span> was set to true, and the first
coefficient of the denominator is always one.
</p></dd>
<dt><span class="term">working-precision N</span></dt>
<dd><p>
Sets the working precision of NTL::RR to <span class="emphasis"><em>N</em></span> binary
digits. Defaults to 250.
</p></dd>
<dt><span class="term">target-precision N</span></dt>
<dd><p>
Sets the precision of printed output to <span class="emphasis"><em>N</em></span> binary
digits: set to the same number of digits as the type that will be used
to evaluate the approximation. Defaults to 53 (for double precision).
</p></dd>
<dt><span class="term">skew val</span></dt>
<dd><p>
"Skews" the initial interpolated control points towards one
end or the other of the range. Positive values skew the initial control
points towards the left hand side of the range, and negative values
towards the right hand side. If an approximation won't converge (a
common situation) try adjusting the skew parameter until the first
step yields the smallest possible error. <span class="emphasis"><em>val</em></span> should
be in the range [-100,+100], the default is zero.
</p></dd>
<dt><span class="term">brake val</span></dt>
<dd><p>
Sets a brake on each step so that the change in the control points
is braked by <span class="emphasis"><em>val%</em></span>. Defaults to 50, try a higher
value if an approximation won't converge, or a lower value to get speedier
convergence.
</p></dd>
<dt><span class="term">x-offset val</span></dt>
<dd><p>
Sets the x-offset to <span class="emphasis"><em>val</em></span>: the approximation will
be generated for <code class="computeroutput"><span class="identifier">f</span><span class="special">(</span><span class="identifier">S</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">x</span> <span class="special">+</span> <span class="identifier">X</span><span class="special">))</span> <span class="special">+</span> <span class="identifier">Y</span></code>
where <span class="emphasis"><em>X</em></span> is the x-offset, <span class="emphasis"><em>S</em></span>
is the x-scale and <span class="emphasis"><em>Y</em></span> is the y-offset. Defaults
to zero. To avoid rounding errors, take care to specify a value that
can be exactly represented as a floating point number.
</p></dd>
<dt><span class="term">x-scale val</span></dt>
<dd><p>
Sets the x-scale to <span class="emphasis"><em>val</em></span>: the approximation will
be generated for <code class="computeroutput"><span class="identifier">f</span><span class="special">(</span><span class="identifier">S</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">x</span> <span class="special">+</span> <span class="identifier">X</span><span class="special">))</span> <span class="special">+</span> <span class="identifier">Y</span></code>
where <span class="emphasis"><em>S</em></span> is the x-scale, <span class="emphasis"><em>X</em></span>
is the x-offset and <span class="emphasis"><em>Y</em></span> is the y-offset. Defaults
to one. To avoid rounding errors, take care to specify a value that
can be exactly represented as a floating point number.
</p></dd>
<dt><span class="term">y-offset val</span></dt>
<dd><p>
Sets the y-offset to <span class="emphasis"><em>val</em></span>: the approximation will
be generated for <code class="computeroutput"><span class="identifier">f</span><span class="special">(</span><span class="identifier">S</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">x</span> <span class="special">+</span> <span class="identifier">X</span><span class="special">))</span> <span class="special">+</span> <span class="identifier">Y</span></code>
where <span class="emphasis"><em>X</em></span> is the x-offset, <span class="emphasis"><em>S</em></span>
is the x-scale and <span class="emphasis"><em>Y</em></span> is the y-offset. Defaults
to zero. To avoid rounding errors, take care to specify a value that
can be exactly represented as a floating point number.
</p></dd>
<dt><span class="term">y-offset auto</span></dt>
<dd><p>
Sets the y-offset to the average value of f(x) evaluated at the two
endpoints of the range plus the midpoint of the range. The calculated
value is deliberately truncated to <span class="emphasis"><em>float</em></span> precision
(and should be stored as a <span class="emphasis"><em>float</em></span> in your code).
The approximation will be generated for <code class="computeroutput"><span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span> <span class="special">+</span> <span class="identifier">X</span><span class="special">)</span> <span class="special">+</span> <span class="identifier">Y</span></code> where <span class="emphasis"><em>X</em></span> is
the x-offset and <span class="emphasis"><em>Y</em></span> is the y-offset. Defaults to
zero.
</p></dd>
<dt><span class="term">graph N</span></dt>
<dd><p>
Prints N evaluations of f(x) at evenly spaced points over the range
being optimised. If unspecified then <span class="emphasis"><em>N</em></span> defaults
to 3. Use to check that f(x) is indeed smooth over the range of interest.
</p></dd>
<dt><span class="term">step N</span></dt>
<dd><p>
Performs <span class="emphasis"><em>N</em></span> steps, or one step if <span class="emphasis"><em>N</em></span>
is unspecified. After each step prints: the peek error at the extrema
of the error function of the approximation, the theoretical error term
solved for on the last step, and the maximum relative change in the
location of the Chebyshev control points. The approximation is converged
on the minimax solution when the two error terms are (approximately)
equal, and the change in the control points has decreased to a suitably
small value.
</p></dd>
<dt><span class="term">test [float|double|long]</span></dt>
<dd><p>
Tests the current approximation at float, double, or long double precision.
Useful to check for rounding errors in evaluating the approximation
at fixed precision. Tests are conducted at the extrema of the error
function of the approximation, and at the zeros of the error function.
</p></dd>
<dt><span class="term">test [float|double|long] N</span></dt>
<dd><p>
Tests the current approximation at float, double, or long double precision.
Useful to check for rounding errors in evaluating the approximation
at fixed precision. Tests are conducted at N evenly spaced points over
the range of the approximation. If none of [float|double|long] are
specified then tests using NTL::RR, this can be used to obtain the
error function of the approximation.
</p></dd>
<dt><span class="term">rescale a b</span></dt>
<dd><p>
Takes the current Chebeshev control points, and rescales them over
a new interval [a,b]. Sometimes this can be used to obtain starting
control points for an approximation that can not otherwise be converged.
</p></dd>
<dt><span class="term">rotate</span></dt>
<dd><p>
Moves one term from the numerator to the denominator, but keeps the
Chebyshev control points the same. Sometimes this can be used to obtain
starting control points for an approximation that can not otherwise
be converged.
</p></dd>
<dt><span class="term">info</span></dt>
<dd><p>
Prints out the current approximation: the location of the zeros of
the error function, the location of the Chebyshev control points, the
x and y offsets, and of course the coefficients of the polynomials.
</p></dd>
</dl>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2006-2010, 2012-2014, 2017 Nikhar
Agrawal, Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos,
Hubert Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan R&#229;de, Gautam
Sewani, Benjamin Sobotta, Nicholas Thompson, Thijs van den Berg, Daryle Walker
and Xiaogang Zhang<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tuples.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="error_test.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,198 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<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="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">
</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="../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>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="math_toolkit.internals.series_evaluation"></a><a class="link" href="series_evaluation.html" title="Series Evaluation">Series Evaluation</a>
</h3></div></div></div>
<h5>
<a name="math_toolkit.internals.series_evaluation.h0"></a>
<span class="phrase"><a name="math_toolkit.internals.series_evaluation.synopsis"></a></span><a class="link" href="series_evaluation.html#math_toolkit.internals.series_evaluation.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">series</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">Functor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">&gt;</span>
<span class="keyword">inline</span> <span class="keyword">typename</span> <span class="identifier">Functor</span><span class="special">::</span><span class="identifier">result_type</span> <span class="identifier">sum_series</span><span class="special">(</span><span class="identifier">Functor</span><span class="special">&amp;</span> <span class="identifier">func</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">U</span><span class="special">&amp;</span> <span class="identifier">tolerance</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_terms</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">V</span><span class="special">&amp;</span> <span class="identifier">init_value</span><span class="special">);</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Functor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">&gt;</span>
<span class="keyword">inline</span> <span class="keyword">typename</span> <span class="identifier">Functor</span><span class="special">::</span><span class="identifier">result_type</span> <span class="identifier">sum_series</span><span class="special">(</span><span class="identifier">Functor</span><span class="special">&amp;</span> <span class="identifier">func</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">U</span><span class="special">&amp;</span> <span class="identifier">tolerance</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_terms</span><span class="special">);</span>
<span class="comment">//</span>
<span class="comment">// The following interfaces are now deprecated:</span>
<span class="comment">// </span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Functor</span><span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">Functor</span><span class="special">::</span><span class="identifier">result_type</span> <span class="identifier">sum_series</span><span class="special">(</span><span class="identifier">Functor</span><span class="special">&amp;</span> <span class="identifier">func</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">bits</span><span class="special">);</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Functor</span><span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">Functor</span><span class="special">::</span><span class="identifier">result_type</span> <span class="identifier">sum_series</span><span class="special">(</span><span class="identifier">Functor</span><span class="special">&amp;</span> <span class="identifier">func</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">bits</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&amp;</span> <span class="identifier">max_terms</span><span class="special">);</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Functor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">Functor</span><span class="special">::</span><span class="identifier">result_type</span> <span class="identifier">sum_series</span><span class="special">(</span><span class="identifier">Functor</span><span class="special">&amp;</span> <span class="identifier">func</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">bits</span><span class="special">,</span> <span class="identifier">U</span> <span class="identifier">init_value</span><span class="special">);</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Functor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">Functor</span><span class="special">::</span><span class="identifier">result_type</span> <span class="identifier">sum_series</span><span class="special">(</span><span class="identifier">Functor</span><span class="special">&amp;</span> <span class="identifier">func</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">bits</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&amp;</span> <span class="identifier">max_terms</span><span class="special">,</span> <span class="identifier">U</span> <span class="identifier">init_value</span><span class="special">);</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Functor</span><span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">Functor</span><span class="special">::</span><span class="identifier">result_type</span> <span class="identifier">kahan_sum_series</span><span class="special">(</span><span class="identifier">Functor</span><span class="special">&amp;</span> <span class="identifier">func</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">bits</span><span class="special">);</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Functor</span><span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">Functor</span><span class="special">::</span><span class="identifier">result_type</span> <span class="identifier">kahan_sum_series</span><span class="special">(</span><span class="identifier">Functor</span><span class="special">&amp;</span> <span class="identifier">func</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">bits</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">&amp;</span> <span class="identifier">max_terms</span><span class="special">);</span>
<span class="special">}}}</span> <span class="comment">// namespaces</span>
</pre>
<h5>
<a name="math_toolkit.internals.series_evaluation.h1"></a>
<span class="phrase"><a name="math_toolkit.internals.series_evaluation.description"></a></span><a class="link" href="series_evaluation.html#math_toolkit.internals.series_evaluation.description">Description</a>
</h5>
<p>
These algorithms are intended for the <a href="http://en.wikipedia.org/wiki/Series_%28mathematics%29" target="_top">summation
of infinite series</a>.
</p>
<p>
Each of the algorithms takes a nullary-function object as the first argument:
the function object will be repeatedly invoked to pull successive terms from
the series being summed.
</p>
<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.
</p>
<p>
The third argument <span class="emphasis"><em>max_terms</em></span> sets an upper limit on
the number of terms of the series to evaluate. In addition, on exit the function
will set <span class="emphasis"><em>max_terms</em></span> to the actual number of terms of
the series that were evaluated: this is particularly useful for profiling
the convergence properties of a new series.
</p>
<p>
The final optional argument <span class="emphasis"><em>init_value</em></span> is the initial
value of the sum to which the terms of the series should be added. This is
useful in two situations:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Where the first value of the series has a different formula to successive
terms. In this case the first value in the series can be passed as the
last argument and the logic of the function object can then be simplified
to return subsequent terms.
</li>
<li class="listitem">
Where the series is being added (or subtracted) from some other value:
termination of the series will likely occur much more rapidly if that
other value is passed as the last argument. For example, there are several
functions that can be expressed as <span class="emphasis"><em>1 - S(z)</em></span> where
S(z) is an infinite series. In this case, pass -1 as the last argument
and then negate the result of the summation to get the result of <span class="emphasis"><em>1
- S(z)</em></span>.
</li>
</ul></div>
<p>
The two <span class="emphasis"><em>kahan_sum_series</em></span> variants of these algorithms
maintain a carry term that corrects for roundoff error during summation.
They are inspired by the <a href="http://en.wikipedia.org/wiki/Kahan_Summation_Algorithm" target="_top"><span class="emphasis"><em>Kahan
Summation Formula</em></span></a> that appears in <a href="http://docs.sun.com/source/806-3568/ncg_goldberg.html" target="_top">What
Every Computer Scientist Should Know About Floating-Point Arithmetic</a>.
However, it should be pointed out that there are very few series that require
summation in this way.
</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>
</h5>
<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>
<p>
We begin by writing a small function object to return successive terms of
the series:
</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">{</span>
<span class="comment">// we must define a result_type typedef:</span>
<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="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">// 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>
<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">T</span> <span class="identifier">m_mult</span><span class="special">;</span>
<span class="identifier">T</span> <span class="identifier">m_prod</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<p>
Implementing log(1+x) is now fairly trivial:
</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="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="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="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>
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="../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>
</div>
</body>
</html>

View File

@@ -0,0 +1,564 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<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="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">
</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="error_test.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="../../using_udt.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.test_data"></a><a class="link" href="test_data.html" title="Graphing, Profiling, and Generating Test Data for Special Functions">Graphing, Profiling,
and Generating Test Data for Special Functions</a>
</h3></div></div></div>
<p>
The class <code class="computeroutput"><span class="identifier">test_data</span></code> and associated
helper functions are designed so that in just a few lines of code you should
be able to:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Profile a continued fraction, or infinite series for convergence and
accuracy.
</li>
<li class="listitem">
Generate csv data from a special function that can be imported into your
favorite graphing program (or spreadsheet) for further analysis.
</li>
<li class="listitem">
Generate high precision test data.
</li>
</ul></div>
<h5>
<a name="math_toolkit.internals.test_data.h0"></a>
<span class="phrase"><a name="math_toolkit.internals.test_data.synopsis"></a></span><a class="link" href="test_data.html#math_toolkit.internals.test_data.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">test_data</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
This is a non-core Boost.Math header that is predominantly used for internal
maintenance of the library: as a result the library 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 you will need to
add that directory to your include path in order to use this feature.
</p></td></tr>
</table></div>
<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">enum</span> <span class="identifier">parameter_type</span>
<span class="special">{</span>
<span class="identifier">random_in_range</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span>
<span class="identifier">periodic_in_range</span> <span class="special">=</span> <span class="number">1</span><span class="special">,</span>
<span class="identifier">power_series</span> <span class="special">=</span> <span class="number">2</span><span class="special">,</span>
<span class="identifier">dummy_param</span> <span class="special">=</span> <span class="number">0x80</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="keyword">struct</span> <span class="identifier">parameter_info</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">parameter_info</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">make_random_param</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">start_range</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">end_range</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">n_points</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">parameter_info</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">make_periodic_param</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">start_range</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">end_range</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">n_points</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">parameter_info</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">make_power_param</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">basis</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">start_exponent</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">end_exponent</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="keyword">bool</span> <span class="identifier">get_user_parameter_info</span><span class="special">(</span><span class="identifier">parameter_info</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">info</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">param_name</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="keyword">class</span> <span class="identifier">test_data</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">vector</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">row_type</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">row_type</span> <span class="identifier">value_type</span><span class="special">;</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">set</span><span class="special">&lt;</span><span class="identifier">row_type</span><span class="special">&gt;</span> <span class="identifier">container_type</span><span class="special">;</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">container_type</span><span class="special">::</span><span class="identifier">reference</span> <span class="identifier">reference</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">container_type</span><span class="special">::</span><span class="identifier">const_reference</span> <span class="identifier">const_reference</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">container_type</span><span class="special">::</span><span class="identifier">iterator</span> <span class="identifier">iterator</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">container_type</span><span class="special">::</span><span class="identifier">const_iterator</span> <span class="identifier">const_iterator</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">container_type</span><span class="special">::</span><span class="identifier">difference_type</span> <span class="identifier">difference_type</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">container_type</span><span class="special">::</span><span class="identifier">size_type</span> <span class="identifier">size_type</span><span class="special">;</span>
<span class="comment">// creation:</span>
<span class="identifier">test_data</span><span class="special">(){}</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">&gt;</span>
<span class="identifier">test_data</span><span class="special">(</span><span class="identifier">F</span> <span class="identifier">func</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">parameter_info</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">arg1</span><span class="special">);</span>
<span class="comment">// insertion:</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">&gt;</span>
<span class="identifier">test_data</span><span class="special">&amp;</span> <span class="identifier">insert</span><span class="special">(</span><span class="identifier">F</span> <span class="identifier">func</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">parameter_info</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">arg1</span><span class="special">);</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">&gt;</span>
<span class="identifier">test_data</span><span class="special">&amp;</span> <span class="identifier">insert</span><span class="special">(</span><span class="identifier">F</span> <span class="identifier">func</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">parameter_info</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">arg1</span><span class="special">,</span>
<span class="keyword">const</span> <span class="identifier">parameter_info</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">arg2</span><span class="special">);</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">&gt;</span>
<span class="identifier">test_data</span><span class="special">&amp;</span> <span class="identifier">insert</span><span class="special">(</span><span class="identifier">F</span> <span class="identifier">func</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">parameter_info</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">arg1</span><span class="special">,</span>
<span class="keyword">const</span> <span class="identifier">parameter_info</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">arg2</span><span class="special">,</span>
<span class="keyword">const</span> <span class="identifier">parameter_info</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">arg3</span><span class="special">);</span>
<span class="keyword">void</span> <span class="identifier">clear</span><span class="special">();</span>
<span class="comment">// access:</span>
<span class="identifier">iterator</span> <span class="identifier">begin</span><span class="special">();</span>
<span class="identifier">iterator</span> <span class="identifier">end</span><span class="special">();</span>
<span class="identifier">const_iterator</span> <span class="identifier">begin</span><span class="special">()</span><span class="keyword">const</span><span class="special">;</span>
<span class="identifier">const_iterator</span> <span class="identifier">end</span><span class="special">()</span><span class="keyword">const</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="keyword">const</span> <span class="identifier">test_data</span><span class="special">&amp;</span> <span class="identifier">d</span><span class="special">)</span><span class="keyword">const</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="keyword">const</span> <span class="identifier">test_data</span><span class="special">&amp;</span> <span class="identifier">d</span><span class="special">)</span><span class="keyword">const</span><span class="special">;</span>
<span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">test_data</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">);</span>
<span class="identifier">size_type</span> <span class="identifier">size</span><span class="special">()</span><span class="keyword">const</span><span class="special">;</span>
<span class="identifier">size_type</span> <span class="identifier">max_size</span><span class="special">()</span><span class="keyword">const</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="identifier">empty</span><span class="special">()</span><span class="keyword">const</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">test_data</span><span class="special">&amp;</span> <span class="identifier">dat</span><span class="special">)</span><span class="keyword">const</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">test_data</span><span class="special">&amp;</span> <span class="identifier">dat</span><span class="special">)</span><span class="keyword">const</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">test_data</span><span class="special">&amp;</span> <span class="identifier">dat</span><span class="special">)</span><span class="keyword">const</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">test_data</span><span class="special">&amp;</span> <span class="identifier">dat</span><span class="special">)</span><span class="keyword">const</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">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traits</span><span class="special">&gt;&amp;</span> <span class="identifier">write_csv</span><span class="special">(</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traits</span><span class="special">&gt;&amp;</span> <span class="identifier">os</span><span class="special">,</span>
<span class="keyword">const</span> <span class="identifier">test_data</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">data</span><span class="special">);</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traits</span><span class="special">&gt;&amp;</span> <span class="identifier">write_csv</span><span class="special">(</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traits</span><span class="special">&gt;&amp;</span> <span class="identifier">os</span><span class="special">,</span>
<span class="keyword">const</span> <span class="identifier">test_data</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">data</span><span class="special">,</span>
<span class="keyword">const</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">separator</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">ostream</span><span class="special">&amp;</span> <span class="identifier">write_code</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="identifier">os</span><span class="special">,</span>
<span class="keyword">const</span> <span class="identifier">test_data</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">data</span><span class="special">,</span>
<span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">name</span><span class="special">);</span>
<span class="special">}}}</span> <span class="comment">// namespaces</span>
</pre>
<h5>
<a name="math_toolkit.internals.test_data.h1"></a>
<span class="phrase"><a name="math_toolkit.internals.test_data.description"></a></span><a class="link" href="test_data.html#math_toolkit.internals.test_data.description">Description</a>
</h5>
<p>
This tool is best illustrated with the following series of examples.
</p>
<p>
The functionality of test_data is split into the following parts:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
A functor that implements the function for which data is being generated:
this is the bit you have to write.
</li>
<li class="listitem">
One of more parameters that are to be passed to the functor, these are
described in fairly abstract terms: give me N points distributed like
<span class="emphasis"><em>this</em></span> etc.
</li>
<li class="listitem">
The class test_data, that takes the functor and descriptions of the parameters
and computes how ever many output points have been requested, these are
stored in a sorted container.
</li>
<li class="listitem">
Routines to iterate over the test_data container and output the data
in either csv format, or as C++ source code (as a table using Boost.Array).
</li>
</ul></div>
<h6>
<a name="math_toolkit.internals.test_data.h2"></a>
<span class="phrase"><a name="math_toolkit.internals.test_data.example_1_output_data_for_graph_"></a></span><a class="link" href="test_data.html#math_toolkit.internals.test_data.example_1_output_data_for_graph_">Example
1: Output Data for Graph Plotting</a>
</h6>
<p>
For example, lets say we want to graph the lgamma function between -3 and
100, one could do this like so:
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">tools</span><span class="special">/</span><span class="identifier">test_data</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<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">special_functions</span><span class="special">/</span><span class="identifier">gamma</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">int</span> <span class="identifier">main</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">// create an object to hold the data:</span>
<span class="identifier">test_data</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">data</span><span class="special">;</span>
<span class="comment">// insert 500 points at uniform intervals between just after -3 and 100:</span>
<span class="keyword">double</span> <span class="special">(*</span><span class="identifier">pf</span><span class="special">)(</span><span class="keyword">double</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">lgamma</span><span class="special">;</span>
<span class="identifier">data</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">pf</span><span class="special">,</span> <span class="identifier">make_periodic_param</span><span class="special">(-</span><span class="number">3.0</span> <span class="special">+</span> <span class="number">0.00001</span><span class="special">,</span> <span class="number">100.0</span><span class="special">,</span> <span class="number">500</span><span class="special">));</span>
<span class="comment">// print out in csv format:</span>
<span class="identifier">write_csv</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">,</span> <span class="identifier">data</span><span class="special">,</span> <span class="string">", "</span><span class="special">);</span>
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
Which, when plotted, results in:
</p>
<p>
<span class="inlinemediaobject"><img src="../../../graphs/lgamma.svg" align="middle"></span>
</p>
<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
2: Creating Test Data</a>
</h6>
<p>
As a second example, let's suppose we want to create highly accurate test
data for a special function. Since many special functions have two or more
independent parameters, it's very hard to effectively cover all of the possible
parameter space without generating gigabytes of data at great computational
expense. A second best approach is to provide the tools by which a user (or
the library maintainer) can quickly generate more data on demand to probe
the function over a particular domain of interest.
</p>
<p>
In this example we'll generate test data for the beta function using <a href="http://shoup.net/ntl/doc/RR.txt" target="_top">NTL::RR</a> at 1000 bit precision.
Rather than call our generic version of the beta function, we'll implement
a deliberately naive version of the beta function using lgamma, and rely
on the high precision of the data type used to get results accurate to at
least 128-bit precision. In this way our test data is independent of whatever
clever tricks we may wish to use inside the our beta function.
</p>
<p>
To start with then, here's the function object that creates the test data:
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">tools</span><span class="special">/</span><span class="identifier">ntl</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<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">special_functions</span><span class="special">/</span><span class="identifier">gamma</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<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">test_data</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">fstream</span><span class="special">&gt;</span>
<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">test_data</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">tools</span><span class="special">;</span>
<span class="keyword">struct</span> <span class="identifier">beta_data_generator</span>
<span class="special">{</span>
<span class="identifier">NTL</span><span class="special">::</span><span class="identifier">RR</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">NTL</span><span class="special">::</span><span class="identifier">RR</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">NTL</span><span class="special">::</span><span class="identifier">RR</span> <span class="identifier">b</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">//</span>
<span class="comment">// If we throw a domain error then test_data will</span>
<span class="comment">// ignore this input point. We'll use this to filter</span>
<span class="comment">// out all cases where a &lt; b since the beta function</span>
<span class="comment">// is symmetrical in a and b:</span>
<span class="comment">//</span>
<span class="keyword">if</span><span class="special">(</span><span class="identifier">a</span> <span class="special">&lt;</span> <span class="identifier">b</span><span class="special">)</span>
<span class="keyword">throw</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">domain_error</span><span class="special">(</span><span class="string">""</span><span class="special">);</span>
<span class="comment">// very naively calculate spots with lgamma:</span>
<span class="identifier">NTL</span><span class="special">::</span><span class="identifier">RR</span> <span class="identifier">g1</span><span class="special">,</span> <span class="identifier">g2</span><span class="special">,</span> <span class="identifier">g3</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">s1</span><span class="special">,</span> <span class="identifier">s2</span><span class="special">,</span> <span class="identifier">s3</span><span class="special">;</span>
<span class="identifier">g1</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">lgamma</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">s1</span><span class="special">);</span>
<span class="identifier">g2</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">lgamma</span><span class="special">(</span><span class="identifier">b</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">s2</span><span class="special">);</span>
<span class="identifier">g3</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">lgamma</span><span class="special">(</span><span class="identifier">a</span><span class="special">+</span><span class="identifier">b</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">s3</span><span class="special">);</span>
<span class="identifier">g1</span> <span class="special">+=</span> <span class="identifier">g2</span> <span class="special">-</span> <span class="identifier">g3</span><span class="special">;</span>
<span class="identifier">g1</span> <span class="special">=</span> <span class="identifier">exp</span><span class="special">(</span><span class="identifier">g1</span><span class="special">);</span>
<span class="identifier">g1</span> <span class="special">*=</span> <span class="identifier">s1</span> <span class="special">*</span> <span class="identifier">s2</span> <span class="special">*</span> <span class="identifier">s3</span><span class="special">;</span>
<span class="keyword">return</span> <span class="identifier">g1</span><span class="special">;</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
To create the data, we'll need to input the domains for a and b for which
the function will be tested: the function <code class="computeroutput"><span class="identifier">get_user_parameter_info</span></code>
is designed for just that purpose. The start of main will look something
like:
</p>
<pre class="programlisting"><span class="comment">// Set the precision on RR:</span>
<span class="identifier">NTL</span><span class="special">::</span><span class="identifier">RR</span><span class="special">::</span><span class="identifier">SetPrecision</span><span class="special">(</span><span class="number">1000</span><span class="special">);</span> <span class="comment">// bits.</span>
<span class="identifier">NTL</span><span class="special">::</span><span class="identifier">RR</span><span class="special">::</span><span class="identifier">SetOutputPrecision</span><span class="special">(</span><span class="number">40</span><span class="special">);</span> <span class="comment">// decimal digits.</span>
<span class="identifier">parameter_info</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">arg1</span><span class="special">,</span> <span class="identifier">arg2</span><span class="special">;</span>
<span class="identifier">test_data</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">data</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">"Welcome.\n"</span>
<span class="string">"This program will generate spot tests for the beta function:\n"</span>
<span class="string">" beta(a, b)\n\n"</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="identifier">cont</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">line</span><span class="special">;</span>
<span class="keyword">do</span><span class="special">{</span>
<span class="comment">// prompt the user for the domain of a and b to test:</span>
<span class="identifier">get_user_parameter_info</span><span class="special">(</span><span class="identifier">arg1</span><span class="special">,</span> <span class="string">"a"</span><span class="special">);</span>
<span class="identifier">get_user_parameter_info</span><span class="special">(</span><span class="identifier">arg2</span><span class="special">,</span> <span class="string">"b"</span><span class="special">);</span>
<span class="comment">// create the data:</span>
<span class="identifier">data</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">beta_data_generator</span><span class="special">(),</span> <span class="identifier">arg1</span><span class="special">,</span> <span class="identifier">arg2</span><span class="special">);</span>
<span class="comment">// see if the user want's any more domains tested:</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Any more data [y/n]?"</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">getline</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cin</span><span class="special">,</span> <span class="identifier">line</span><span class="special">);</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">trim</span><span class="special">(</span><span class="identifier">line</span><span class="special">);</span>
<span class="identifier">cont</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">line</span> <span class="special">==</span> <span class="string">"y"</span><span class="special">);</span>
<span class="special">}</span><span class="keyword">while</span><span class="special">(</span><span class="identifier">cont</span><span class="special">);</span>
</pre>
<div class="caution"><table border="0" summary="Caution">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="../../../../../../doc/src/images/caution.png"></td>
<th align="left">Caution</th>
</tr>
<tr><td align="left" valign="top"><p>
At this point one potential stumbling block should be mentioned: test_data&lt;&gt;::insert
will create a matrix of test data when there are two or more parameters,
so if we have two parameters and we're asked for a thousand points on each,
that's a <span class="emphasis"><em>million test points in total</em></span>. Don't say you
weren't warned!
</p></td></tr>
</table></div>
<p>
There's just one final step now, and that's to write the test data to file:
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Enter name of test data file [default=beta_data.ipp]"</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">getline</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cin</span><span class="special">,</span> <span class="identifier">line</span><span class="special">);</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">trim</span><span class="special">(</span><span class="identifier">line</span><span class="special">);</span>
<span class="keyword">if</span><span class="special">(</span><span class="identifier">line</span> <span class="special">==</span> <span class="string">""</span><span class="special">)</span>
<span class="identifier">line</span> <span class="special">=</span> <span class="string">"beta_data.ipp"</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">ofstream</span> <span class="identifier">ofs</span><span class="special">(</span><span class="identifier">line</span><span class="special">.</span><span class="identifier">c_str</span><span class="special">());</span>
<span class="identifier">write_code</span><span class="special">(</span><span class="identifier">ofs</span><span class="special">,</span> <span class="identifier">data</span><span class="special">,</span> <span class="string">"beta_data"</span><span class="special">);</span>
</pre>
<p>
The format of the test data looks something like:
</p>
<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">SC_</span><span class="special">(</span><span class="identifier">x</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">BOOST_JOIN</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">L</span><span class="special">))</span>
<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">T</span><span class="special">,</span> <span class="number">3</span><span class="special">&gt;,</span> <span class="number">1830</span><span class="special">&gt;</span>
<span class="identifier">beta_med_data</span> <span class="special">=</span> <span class="special">{</span>
<span class="identifier">SC_</span><span class="special">(</span><span class="number">0.4883005917072296142578125</span><span class="special">),</span>
<span class="identifier">SC_</span><span class="special">(</span><span class="number">0.4883005917072296142578125</span><span class="special">),</span>
<span class="identifier">SC_</span><span class="special">(</span><span class="number">3.245912809500479157065104747353807392371</span><span class="special">),</span>
<span class="identifier">SC_</span><span class="special">(</span><span class="number">3.5808107852935791015625</span><span class="special">),</span>
<span class="identifier">SC_</span><span class="special">(</span><span class="number">0.4883005917072296142578125</span><span class="special">),</span>
<span class="identifier">SC_</span><span class="special">(</span><span class="number">1.007653173802923954909901438393379243537</span><span class="special">),</span>
<span class="comment">/* ... lots of rows skipped */</span>
<span class="special">};</span>
</pre>
<p>
The first two values in each row are the input parameters that were passed
to our functor and the last value is the return value from the functor. Had
our functor returned a <a class="link" href="tuples.html" title="Tuples">boost::math::tuple</a>
rather than a value, then we would have had one entry for each element in
the tuple in addition to the input parameters.
</p>
<p>
The first #define serves two purposes:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
It reduces the file sizes considerably: all those <code class="computeroutput"><span class="keyword">static_cast</span></code>'s
add up to a lot of bytes otherwise (they are needed to suppress compiler
warnings when <code class="computeroutput"><span class="identifier">T</span></code> is narrower
than a <code class="computeroutput"><span class="keyword">long</span> <span class="keyword">double</span></code>).
</li>
<li class="listitem">
It provides a useful customisation point: for example if we were testing
a user-defined type that has more precision than a <code class="computeroutput"><span class="keyword">long</span>
<span class="keyword">double</span></code> we could change it to:
</li>
</ul></div>
<p>
<code class="literal">#define SC_(x) lexical_cast&lt;T&gt;(BOOST_STRINGIZE(x))</code>
</p>
<p>
in order to ensure that no truncation of the values occurs prior to conversion
to <code class="computeroutput"><span class="identifier">T</span></code>. Note that this isn't
used by default as it's rather hard on the compiler when the table is large.
</p>
<h6>
<a name="math_toolkit.internals.test_data.h4"></a>
<span class="phrase"><a name="math_toolkit.internals.test_data.example_3_profiling_a_continued_"></a></span><a class="link" href="test_data.html#math_toolkit.internals.test_data.example_3_profiling_a_continued_">Example
3: Profiling a Continued Fraction for Convergence and Accuracy</a>
</h6>
<p>
Alternatively, lets say we want to profile a continued fraction for convergence
and error. As an example, we'll use the continued fraction for the upper
incomplete gamma function, the following function object returns the next
a<sub>N </sub> and b<sub>N </sub> of the continued fraction each time it's invoked:
</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="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="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="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">k</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">a</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>
We want to measure both the relative error, and the rate of convergence of
this fraction, so we'll write a functor that returns both as a <a class="link" href="tuples.html" title="Tuples">boost::math::tuple</a>:
class test_data will unpack the tuple for us, and create one column of data
for each element in the tuple (in addition to the input parameters):
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">tools</span><span class="special">/</span><span class="identifier">test_data</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<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">test</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<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">special_functions</span><span class="special">/</span><span class="identifier">gamma</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<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">ntl</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<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">tuple</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</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="keyword">struct</span> <span class="identifier">profile_gamma_fraction</span>
<span class="special">{</span>
<span class="keyword">typedef</span> <a class="link" href="tuples.html" title="Tuples">boost::math::tuple</a><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">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">// 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">// 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>
<span class="identifier">T</span> <span class="identifier">found_val</span> <span class="special">=</span> <span class="identifier">continued_fraction_a</span><span class="special">(</span><span class="identifier">f2</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">digits</span><span class="special">,</span> <span class="identifier">iters</span><span class="special">);</span>
<span class="comment">//</span>
<span class="comment">// Work out the relative error, as measured in units of epsilon:</span>
<span class="identifier">T</span> <span class="identifier">err</span> <span class="special">=</span> <span class="identifier">real_cast</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;(</span><span class="identifier">relative_error</span><span class="special">(</span><span class="identifier">true_val</span><span class="special">,</span> <span class="identifier">NTL</span><span class="special">::</span><span class="identifier">RR</span><span class="special">(</span><span class="identifier">found_val</span><span class="special">))</span> <span class="special">/</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">epsilon</span><span class="special">());</span>
<span class="comment">//</span>
<span class="comment">// now just return the results as a tuple:</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">make_tuple</span><span class="special">(</span><span class="identifier">err</span><span class="special">,</span> <span class="identifier">iters</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
Feeding that functor into test_data allows rapid output of csv data, for
whatever type <code class="computeroutput"><span class="identifier">T</span></code> we may be
interested in:
</p>
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</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">// create an object to hold the data:</span>
<span class="identifier">test_data</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">data</span><span class="special">;</span>
<span class="comment">// insert 500 points at uniform intervals between just after 0 and 100:</span>
<span class="identifier">data</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">profile_gamma_fraction</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;(),</span> <span class="identifier">make_periodic_param</span><span class="special">(</span><span class="number">0.01</span><span class="special">,</span> <span class="number">100.0</span><span class="special">,</span> <span class="number">100</span><span class="special">));</span>
<span class="comment">// print out in csv format:</span>
<span class="identifier">write_csv</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">,</span> <span class="identifier">data</span><span class="special">,</span> <span class="string">", "</span><span class="special">);</span>
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
This time there's no need to plot a graph, the first few rows are:
</p>
<pre class="programlisting"><span class="identifier">a</span> <span class="keyword">and</span> <span class="identifier">z</span><span class="special">,</span> <span class="identifier">Error</span><span class="special">/</span><span class="identifier">epsilon</span><span class="special">,</span> <span class="identifier">Iterations</span> <span class="identifier">required</span>
<span class="number">0.01</span><span class="special">,</span> <span class="number">9723.14</span><span class="special">,</span> <span class="number">4726</span>
<span class="number">1.0099</span><span class="special">,</span> <span class="number">9.54818</span><span class="special">,</span> <span class="number">87</span>
<span class="number">2.0098</span><span class="special">,</span> <span class="number">3.84777</span><span class="special">,</span> <span class="number">40</span>
<span class="number">3.0097</span><span class="special">,</span> <span class="number">0.728358</span><span class="special">,</span> <span class="number">25</span>
<span class="number">4.0096</span><span class="special">,</span> <span class="number">2.39712</span><span class="special">,</span> <span class="number">21</span>
<span class="number">5.0095</span><span class="special">,</span> <span class="number">0.233263</span><span class="special">,</span> <span class="number">16</span>
</pre>
<p>
So it's pretty clear that this fraction shouldn't be used for small values
of a and z.
</p>
<h5>
<a name="math_toolkit.internals.test_data.h5"></a>
<span class="phrase"><a name="math_toolkit.internals.test_data.reference"></a></span><a class="link" href="test_data.html#math_toolkit.internals.test_data.reference">reference</a>
</h5>
<p>
Most of this tool has been described already in the examples above, we'll
just add the following notes on the non-member functions:
</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="identifier">parameter_info</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">make_random_param</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">start_range</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">end_range</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">n_points</span><span class="special">);</span>
</pre>
<p>
Tells class test_data to test <span class="emphasis"><em>n_points</em></span> random values
in the range [start_range,end_range].
</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="identifier">parameter_info</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">make_periodic_param</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">start_range</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">end_range</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">n_points</span><span class="special">);</span>
</pre>
<p>
Tells class test_data to test <span class="emphasis"><em>n_points</em></span> evenly spaced
values in the range [start_range,end_range].
</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="identifier">parameter_info</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">make_power_param</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">basis</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">start_exponent</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">end_exponent</span><span class="special">);</span>
</pre>
<p>
Tells class test_data to test points of the form <span class="emphasis"><em>basis + R * 2<sup>expon</sup></em></span>
for each <span class="emphasis"><em>expon</em></span> in the range [start_exponent, end_exponent],
and <span class="emphasis"><em>R</em></span> a random number in [0.5, 1].
</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">bool</span> <span class="identifier">get_user_parameter_info</span><span class="special">(</span><span class="identifier">parameter_info</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">info</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">param_name</span><span class="special">);</span>
</pre>
<p>
Prompts the user for the parameter range and form to use.
</p>
<p>
Finally, if we don't want the parameter to be included in the output, we
can tell test_data by setting it a "dummy parameter":
</p>
<pre class="programlisting"><span class="identifier">parameter_info</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">p</span> <span class="special">=</span> <span class="identifier">make_random_param</span><span class="special">(</span><span class="number">2.0</span><span class="special">,</span> <span class="number">5.0</span><span class="special">,</span> <span class="number">10</span><span class="special">);</span>
<span class="identifier">p</span><span class="special">.</span><span class="identifier">type</span> <span class="special">|=</span> <span class="identifier">dummy_param</span><span class="special">;</span>
</pre>
<p>
This is useful when the functor used transforms the parameter in some way
before passing it to the function under test, usually the functor will then
return both the transformed input and the result in a tuple, so there's no
need for the original pseudo-parameter to be included in program output.
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2006-2010, 2012-2014, 2017 Nikhar
Agrawal, Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos,
Hubert Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan R&#229;de, Gautam
Sewani, Benjamin Sobotta, Nicholas Thompson, Thijs van den Berg, Daryle Walker
and Xiaogang Zhang<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="error_test.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="../../using_udt.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,86 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<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="up" href="../internals.html" title="Internal tools">
<link rel="prev" href="cf.html" title="Continued Fraction Evaluation">
<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">
<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="minimax.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.tuples"></a><a class="link" href="tuples.html" title="Tuples">Tuples</a>
</h3></div></div></div>
<h5>
<a name="math_toolkit.internals.tuples.h0"></a>
<span class="phrase"><a name="math_toolkit.internals.tuples.synopsis"></a></span><a class="link" href="tuples.html#math_toolkit.internals.tuples.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">tuple</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<h5>
<a name="math_toolkit.internals.tuples.h1"></a>
<span class="phrase"><a name="math_toolkit.internals.tuples.description"></a></span><a class="link" href="tuples.html#math_toolkit.internals.tuples.description">Description</a>
</h5>
<p>
This header defines the type <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">tuple</span></code>,
the associated free functions <code class="computeroutput"><span class="identifier">ignore</span></code>,
<code class="computeroutput"><span class="identifier">tie</span></code>, <code class="computeroutput"><span class="identifier">make_tuple</span></code>,
<code class="computeroutput"><span class="identifier">get</span></code>, and associated types
<code class="computeroutput"><span class="identifier">tuple_size</span></code> and <code class="computeroutput"><span class="identifier">tuple_element</span></code>.
</p>
<p>
These types and functions are aliases for:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span></code> etc when available, otherwise:
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">tr1</span><span class="special">::</span><span class="identifier">tuple</span></code> etc when available, otherwise:
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">tuple</span></code> etc if the compiler supports
it, otherwise:
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">tuple</span></code>.
</li>
</ul></div>
<p>
So this <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">tuple</span></code> is strongly recommended for maximum
portability.
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2006-2010, 2012-2014, 2017 Nikhar
Agrawal, Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos,
Hubert Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan R&#229;de, Gautam
Sewani, Benjamin Sobotta, Nicholas Thompson, Thijs van den Berg, Daryle Walker
and Xiaogang Zhang<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="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>
</div>
</body>
</html>