72e469da0a
[CI SKIP]
566 lines
68 KiB
HTML
566 lines
68 KiB
HTML
<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.11.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 19. 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"><</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">></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"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
|
<span class="keyword">struct</span> <span class="identifier">parameter_info</span><span class="special">;</span>
|
|
|
|
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
|
<span class="identifier">parameter_info</span><span class="special"><</span><span class="identifier">T</span><span class="special">></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"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
|
<span class="identifier">parameter_info</span><span class="special"><</span><span class="identifier">T</span><span class="special">></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"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
|
<span class="identifier">parameter_info</span><span class="special"><</span><span class="identifier">T</span><span class="special">></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"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></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"><</span><span class="identifier">T</span><span class="special">>&</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"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></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"><</span><span class="identifier">T</span><span class="special">></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"><</span><span class="identifier">row_type</span><span class="special">></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"><</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">></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"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">arg1</span><span class="special">);</span>
|
|
|
|
<span class="comment">// insertion:</span>
|
|
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">></span>
|
|
<span class="identifier">test_data</span><span class="special">&</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"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">arg1</span><span class="special">);</span>
|
|
|
|
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">></span>
|
|
<span class="identifier">test_data</span><span class="special">&</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"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">arg1</span><span class="special">,</span>
|
|
<span class="keyword">const</span> <span class="identifier">parameter_info</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">arg2</span><span class="special">);</span>
|
|
|
|
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">></span>
|
|
<span class="identifier">test_data</span><span class="special">&</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"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">arg1</span><span class="special">,</span>
|
|
<span class="keyword">const</span> <span class="identifier">parameter_info</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">arg2</span><span class="special">,</span>
|
|
<span class="keyword">const</span> <span class="identifier">parameter_info</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</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">&</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">&</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">&</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"><</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">test_data</span><span class="special">&</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"><=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">test_data</span><span class="special">&</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">></span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">test_data</span><span class="special">&</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">>=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">test_data</span><span class="special">&</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"><</span><span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special"><</span><span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traits</span><span class="special">>&</span> <span class="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"><</span><span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traits</span><span class="special">>&</span> <span class="identifier">os</span><span class="special">,</span>
|
|
<span class="keyword">const</span> <span class="identifier">test_data</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">data</span><span class="special">);</span>
|
|
|
|
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special"><</span><span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traits</span><span class="special">>&</span> <span class="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"><</span><span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traits</span><span class="special">>&</span> <span class="identifier">os</span><span class="special">,</span>
|
|
<span class="keyword">const</span> <span class="identifier">test_data</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">data</span><span class="special">,</span>
|
|
<span class="keyword">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"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&</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">&</span> <span class="identifier">os</span><span class="special">,</span>
|
|
<span class="keyword">const</span> <span class="identifier">test_data</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">data</span><span class="special">,</span>
|
|
<span class="keyword">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"><</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">></span>
|
|
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">special_functions</span><span class="special">/</span><span class="identifier">gamma</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></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"><</span><span class="keyword">double</span><span class="special">></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>
|
|
<div class="blockquote"><blockquote class="blockquote"><p>
|
|
<span class="inlinemediaobject"><img src="../../../graphs/lgamma.svg" align="middle"></span>
|
|
|
|
</p></blockquote></div>
|
|
<h6>
|
|
<a name="math_toolkit.internals.test_data.h3"></a>
|
|
<span class="phrase"><a name="math_toolkit.internals.test_data.example_2_creating_test_data"></a></span><a class="link" href="test_data.html#math_toolkit.internals.test_data.example_2_creating_test_data">Example
|
|
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"><</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">></span>
|
|
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">special_functions</span><span class="special">/</span><span class="identifier">gamma</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
|
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">tools</span><span class="special">/</span><span class="identifier">test_data</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
|
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">fstream</span><span class="special">></span>
|
|
|
|
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">tools</span><span class="special">/</span><span class="identifier">test_data</span><span class="special">.</span><span class="identifier">hpp</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="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 < 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"><</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">&</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">&</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">&</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"><</span><span class="identifier">NTL</span><span class="special">::</span><span class="identifier">RR</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="identifier">test_data</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">data</span><span class="special">;</span>
|
|
|
|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"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"><<</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<>::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"><<</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"><</span><span class="identifier">T</span><span class="special">>(</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"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="number">3</span><span class="special">>,</span> <span class="number">1830</span><span class="special">></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<T>(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"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></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"><</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">T</span><span class="special">></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"><</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">></span>
|
|
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">tools</span><span class="special">/</span><span class="identifier">test</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
|
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">special_functions</span><span class="special">/</span><span class="identifier">gamma</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
|
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">tools</span><span class="special">/</span><span class="identifier">ntl</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
|
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">tools</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
|
|
|
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
|
<span class="keyword">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"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></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"><</span><span class="identifier">NTL</span><span class="special">::</span><span class="identifier">RR</span><span class="special">></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"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span><span class="special">>::</span><span class="identifier">max</span><span class="special">();</span>
|
|
<span class="identifier">upper_incomplete_gamma_fract</span><span class="special"><</span><span class="identifier">T</span><span class="special">></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"><</span><span class="identifier">T</span><span class="special">>::</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"><</span><span class="identifier">T</span><span class="special">>(</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"><</span><span class="identifier">T</span><span class="special">>::</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"><</span><span class="keyword">double</span><span class="special">></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"><</span><span class="keyword">double</span><span class="special">>(),</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 <span class="emphasis"><em>a</em></span> and <span class="emphasis"><em>z</em></span>.
|
|
</p>
|
|
<h5>
|
|
<a name="math_toolkit.internals.test_data.h5"></a>
|
|
<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"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
|
<span class="identifier">parameter_info</span><span class="special"><</span><span class="identifier">T</span><span class="special">></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"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
|
<span class="identifier">parameter_info</span><span class="special"><</span><span class="identifier">T</span><span class="special">></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"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
|
<span class="identifier">parameter_info</span><span class="special"><</span><span class="identifier">T</span><span class="special">></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"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></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"><</span><span class="identifier">T</span><span class="special">>&</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"><</span><span class="keyword">double</span><span class="special">></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 © 2006-2019 Nikhar
|
|
Agrawal, Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos,
|
|
Hubert Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Matthew Pulver, Johan
|
|
Råde, Gautam Sewani, Benjamin Sobotta, Nicholas Thompson, Thijs van den Berg,
|
|
Daryle Walker and Xiaogang Zhang<p>
|
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
|
</p>
|
|
</div></td>
|
|
</tr></table>
|
|
<hr>
|
|
<div class="spirit-nav">
|
|
<a accesskey="p" href="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>
|