1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4<title>Graphing, Profiling, and Generating Test Data for Special Functions</title> 5<link rel="stylesheet" href="../../math.css" type="text/css"> 6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1"> 7<link rel="home" href="../../index.html" title="Math Toolkit 2.12.0"> 8<link rel="up" href="../internals.html" title="Internal tools"> 9<link rel="prev" href="error_test.html" title="Relative Error and Testing"> 10<link rel="next" href="../../using_udt.html" title="Chapter 20. Use with User-Defined Floating-Point Types - Boost.Multiprecision and others"> 11</head> 12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> 13<table cellpadding="2" width="100%"><tr> 14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td> 15<td align="center"><a href="../../../../../../index.html">Home</a></td> 16<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td> 17<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> 18<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> 19<td align="center"><a href="../../../../../../more/index.htm">More</a></td> 20</tr></table> 21<hr> 22<div class="spirit-nav"> 23<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> 24</div> 25<div class="section"> 26<div class="titlepage"><div><div><h3 class="title"> 27<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, 28 and Generating Test Data for Special Functions</a> 29</h3></div></div></div> 30<p> 31 The class <code class="computeroutput"><span class="identifier">test_data</span></code> and associated 32 helper functions are designed so that in just a few lines of code you should 33 be able to: 34 </p> 35<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 36<li class="listitem"> 37 Profile a continued fraction, or infinite series for convergence and 38 accuracy. 39 </li> 40<li class="listitem"> 41 Generate csv data from a special function that can be imported into your 42 favorite graphing program (or spreadsheet) for further analysis. 43 </li> 44<li class="listitem"> 45 Generate high precision test data. 46 </li> 47</ul></div> 48<h5> 49<a name="math_toolkit.internals.test_data.h0"></a> 50 <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> 51 </h5> 52<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> 53</pre> 54<div class="important"><table border="0" summary="Important"> 55<tr> 56<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../../doc/src/images/important.png"></td> 57<th align="left">Important</th> 58</tr> 59<tr><td align="left" valign="top"><p> 60 This is a non-core Boost.Math header that is predominantly used for internal 61 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 62 add that directory to your include path in order to use this feature. 63 </p></td></tr> 64</table></div> 65<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> 66 67<span class="keyword">enum</span> <span class="identifier">parameter_type</span> 68<span class="special">{</span> 69 <span class="identifier">random_in_range</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> 70 <span class="identifier">periodic_in_range</span> <span class="special">=</span> <span class="number">1</span><span class="special">,</span> 71 <span class="identifier">power_series</span> <span class="special">=</span> <span class="number">2</span><span class="special">,</span> 72 <span class="identifier">dummy_param</span> <span class="special">=</span> <span class="number">0x80</span><span class="special">,</span> 73<span class="special">};</span> 74 75<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> 76<span class="keyword">struct</span> <span class="identifier">parameter_info</span><span class="special">;</span> 77 78<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> 79<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> 80 81<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> 82<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> 83 84<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> 85<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> 86 87<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> 88<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> 89 90<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> 91<span class="keyword">class</span> <span class="identifier">test_data</span> 92<span class="special">{</span> 93<span class="keyword">public</span><span class="special">:</span> 94 <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> 95 <span class="keyword">typedef</span> <span class="identifier">row_type</span> <span class="identifier">value_type</span><span class="special">;</span> 96<span class="keyword">private</span><span class="special">:</span> 97 <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> 98<span class="keyword">public</span><span class="special">:</span> 99 <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> 100 <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> 101 <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> 102 <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> 103 <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> 104 <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> 105 106 <span class="comment">// creation:</span> 107 <span class="identifier">test_data</span><span class="special">(){}</span> 108 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">></span> 109 <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> 110 111 <span class="comment">// insertion:</span> 112 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">></span> 113 <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> 114 115 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">></span> 116 <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> 117 <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> 118 119 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">></span> 120 <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> 121 <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> 122 <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> 123 124 <span class="keyword">void</span> <span class="identifier">clear</span><span class="special">();</span> 125 126 <span class="comment">// access:</span> 127 <span class="identifier">iterator</span> <span class="identifier">begin</span><span class="special">();</span> 128 <span class="identifier">iterator</span> <span class="identifier">end</span><span class="special">();</span> 129 <span class="identifier">const_iterator</span> <span class="identifier">begin</span><span class="special">()</span><span class="keyword">const</span><span class="special">;</span> 130 <span class="identifier">const_iterator</span> <span class="identifier">end</span><span class="special">()</span><span class="keyword">const</span><span class="special">;</span> 131 <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> 132 <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> 133 <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> 134 <span class="identifier">size_type</span> <span class="identifier">size</span><span class="special">()</span><span class="keyword">const</span><span class="special">;</span> 135 <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> 136 <span class="keyword">bool</span> <span class="identifier">empty</span><span class="special">()</span><span class="keyword">const</span><span class="special">;</span> 137 138 <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> 139 <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> 140 <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> 141 <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> 142<span class="special">};</span> 143 144<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> 145<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> 146 <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> 147 <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> 148 149<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> 150<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> 151 <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> 152 <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> 153 <span class="keyword">const</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">separator</span><span class="special">);</span> 154 155<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> 156<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> 157 <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> 158 <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">name</span><span class="special">);</span> 159 160<span class="special">}}}</span> <span class="comment">// namespaces</span> 161</pre> 162<h5> 163<a name="math_toolkit.internals.test_data.h1"></a> 164 <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> 165 </h5> 166<p> 167 This tool is best illustrated with the following series of examples. 168 </p> 169<p> 170 The functionality of test_data is split into the following parts: 171 </p> 172<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 173<li class="listitem"> 174 A functor that implements the function for which data is being generated: 175 this is the bit you have to write. 176 </li> 177<li class="listitem"> 178 One of more parameters that are to be passed to the functor, these are 179 described in fairly abstract terms: give me N points distributed like 180 <span class="emphasis"><em>this</em></span> etc. 181 </li> 182<li class="listitem"> 183 The class test_data, that takes the functor and descriptions of the parameters 184 and computes how ever many output points have been requested, these are 185 stored in a sorted container. 186 </li> 187<li class="listitem"> 188 Routines to iterate over the test_data container and output the data 189 in either csv format, or as C++ source code (as a table using Boost.Array). 190 </li> 191</ul></div> 192<h6> 193<a name="math_toolkit.internals.test_data.h2"></a> 194 <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 195 1: Output Data for Graph Plotting</a> 196 </h6> 197<p> 198 For example, lets say we want to graph the lgamma function between -3 and 199 100, one could do this like so: 200 </p> 201<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> 202<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> 203 204<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> 205<span class="special">{</span> 206 <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> 207 208 <span class="comment">// create an object to hold the data:</span> 209 <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> 210 211 <span class="comment">// insert 500 points at uniform intervals between just after -3 and 100:</span> 212 <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> 213 <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> 214 215 <span class="comment">// print out in csv format:</span> 216 <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> 217 <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> 218<span class="special">}</span> 219</pre> 220<p> 221 Which, when plotted, results in: 222 </p> 223<div class="blockquote"><blockquote class="blockquote"><p> 224 <span class="inlinemediaobject"><img src="../../../graphs/lgamma.svg" align="middle"></span> 225 226 </p></blockquote></div> 227<h6> 228<a name="math_toolkit.internals.test_data.h3"></a> 229 <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 230 2: Creating Test Data</a> 231 </h6> 232<p> 233 As a second example, let's suppose we want to create highly accurate test 234 data for a special function. Since many special functions have two or more 235 independent parameters, it's very hard to effectively cover all of the possible 236 parameter space without generating gigabytes of data at great computational 237 expense. A second best approach is to provide the tools by which a user (or 238 the library maintainer) can quickly generate more data on demand to probe 239 the function over a particular domain of interest. 240 </p> 241<p> 242 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. 243 Rather than call our generic version of the beta function, we'll implement 244 a deliberately naive version of the beta function using lgamma, and rely 245 on the high precision of the data type used to get results accurate to at 246 least 128-bit precision. In this way our test data is independent of whatever 247 clever tricks we may wish to use inside the our beta function. 248 </p> 249<p> 250 To start with then, here's the function object that creates the test data: 251 </p> 252<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> 253<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> 254<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> 255<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">fstream</span><span class="special">></span> 256 257<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> 258 259<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> 260 261<span class="keyword">struct</span> <span class="identifier">beta_data_generator</span> 262<span class="special">{</span> 263 <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> 264 <span class="special">{</span> 265 <span class="comment">//</span> 266 <span class="comment">// If we throw a domain error then test_data will</span> 267 <span class="comment">// ignore this input point. We'll use this to filter</span> 268 <span class="comment">// out all cases where a < b since the beta function</span> 269 <span class="comment">// is symmetrical in a and b:</span> 270 <span class="comment">//</span> 271 <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> 272 <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> 273 274 <span class="comment">// very naively calculate spots with lgamma:</span> 275 <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> 276 <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> 277 <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> 278 <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> 279 <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> 280 <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> 281 <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> 282 <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> 283 <span class="keyword">return</span> <span class="identifier">g1</span><span class="special">;</span> 284 <span class="special">}</span> 285<span class="special">};</span> 286</pre> 287<p> 288 To create the data, we'll need to input the domains for a and b for which 289 the function will be tested: the function <code class="computeroutput"><span class="identifier">get_user_parameter_info</span></code> 290 is designed for just that purpose. The start of main will look something 291 like: 292 </p> 293<pre class="programlisting"><span class="comment">// Set the precision on RR:</span> 294<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> 295<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> 296 297<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> 298<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> 299 300<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Welcome.\n"</span> 301 <span class="string">"This program will generate spot tests for the beta function:\n"</span> 302 <span class="string">" beta(a, b)\n\n"</span><span class="special">;</span> 303 304<span class="keyword">bool</span> <span class="identifier">cont</span><span class="special">;</span> 305<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">line</span><span class="special">;</span> 306 307<span class="keyword">do</span><span class="special">{</span> 308 <span class="comment">// prompt the user for the domain of a and b to test:</span> 309 <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> 310 <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> 311 312 <span class="comment">// create the data:</span> 313 <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> 314 315 <span class="comment">// see if the user want's any more domains tested:</span> 316 <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> 317 <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> 318 <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> 319 <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> 320<span class="special">}</span><span class="keyword">while</span><span class="special">(</span><span class="identifier">cont</span><span class="special">);</span> 321</pre> 322<div class="caution"><table border="0" summary="Caution"> 323<tr> 324<td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="../../../../../../doc/src/images/caution.png"></td> 325<th align="left">Caution</th> 326</tr> 327<tr><td align="left" valign="top"><p> 328 At this point one potential stumbling block should be mentioned: test_data<>::insert 329 will create a matrix of test data when there are two or more parameters, 330 so if we have two parameters and we're asked for a thousand points on each, 331 that's a <span class="emphasis"><em>million test points in total</em></span>. Don't say you 332 weren't warned! 333 </p></td></tr> 334</table></div> 335<p> 336 There's just one final step now, and that's to write the test data to file: 337 </p> 338<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> 339<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> 340<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> 341<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> 342 <span class="identifier">line</span> <span class="special">=</span> <span class="string">"beta_data.ipp"</span><span class="special">;</span> 343<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> 344<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> 345</pre> 346<p> 347 The format of the test data looks something like: 348 </p> 349<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> 350 <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> 351 <span class="identifier">beta_med_data</span> <span class="special">=</span> <span class="special">{</span> 352 <span class="identifier">SC_</span><span class="special">(</span><span class="number">0.4883005917072296142578125</span><span class="special">),</span> 353 <span class="identifier">SC_</span><span class="special">(</span><span class="number">0.4883005917072296142578125</span><span class="special">),</span> 354 <span class="identifier">SC_</span><span class="special">(</span><span class="number">3.245912809500479157065104747353807392371</span><span class="special">),</span> 355 <span class="identifier">SC_</span><span class="special">(</span><span class="number">3.5808107852935791015625</span><span class="special">),</span> 356 <span class="identifier">SC_</span><span class="special">(</span><span class="number">0.4883005917072296142578125</span><span class="special">),</span> 357 <span class="identifier">SC_</span><span class="special">(</span><span class="number">1.007653173802923954909901438393379243537</span><span class="special">),</span> 358 <span class="comment">/* ... lots of rows skipped */</span> 359<span class="special">};</span> 360</pre> 361<p> 362 The first two values in each row are the input parameters that were passed 363 to our functor and the last value is the return value from the functor. Had 364 our functor returned a <a class="link" href="tuples.html" title="Tuples">boost::math::tuple</a> 365 rather than a value, then we would have had one entry for each element in 366 the tuple in addition to the input parameters. 367 </p> 368<p> 369 The first #define serves two purposes: 370 </p> 371<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 372<li class="listitem"> 373 It reduces the file sizes considerably: all those <code class="computeroutput"><span class="keyword">static_cast</span></code>'s 374 add up to a lot of bytes otherwise (they are needed to suppress compiler 375 warnings when <code class="computeroutput"><span class="identifier">T</span></code> is narrower 376 than a <code class="computeroutput"><span class="keyword">long</span> <span class="keyword">double</span></code>). 377 </li> 378<li class="listitem"> 379 It provides a useful customisation point: for example if we were testing 380 a user-defined type that has more precision than a <code class="computeroutput"><span class="keyword">long</span> 381 <span class="keyword">double</span></code> we could change it to: 382 </li> 383</ul></div> 384<p> 385 <code class="literal">#define SC_(x) lexical_cast<T>(BOOST_STRINGIZE(x))</code> 386 </p> 387<p> 388 in order to ensure that no truncation of the values occurs prior to conversion 389 to <code class="computeroutput"><span class="identifier">T</span></code>. Note that this isn't 390 used by default as it's rather hard on the compiler when the table is large. 391 </p> 392<h6> 393<a name="math_toolkit.internals.test_data.h4"></a> 394 <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 395 3: Profiling a Continued Fraction for Convergence and Accuracy</a> 396 </h6> 397<p> 398 Alternatively, lets say we want to profile a continued fraction for convergence 399 and error. As an example, we'll use the continued fraction for the upper 400 incomplete gamma function, the following function object returns the next 401 a<sub>N </sub> and b<sub>N </sub> of the continued fraction each time it's invoked: 402 </p> 403<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> 404<span class="keyword">struct</span> <span class="identifier">upper_incomplete_gamma_fract</span> 405<span class="special">{</span> 406<span class="keyword">private</span><span class="special">:</span> 407 <span class="identifier">T</span> <span class="identifier">z</span><span class="special">,</span> <span class="identifier">a</span><span class="special">;</span> 408 <span class="keyword">int</span> <span class="identifier">k</span><span class="special">;</span> 409<span class="keyword">public</span><span class="special">:</span> 410 <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> 411 412 <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> 413 <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> 414 <span class="special">{</span> 415 <span class="special">}</span> 416 417 <span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()()</span> 418 <span class="special">{</span> 419 <span class="special">++</span><span class="identifier">k</span><span class="special">;</span> 420 <span class="identifier">z</span> <span class="special">+=</span> <span class="number">2</span><span class="special">;</span> 421 <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> 422 <span class="special">}</span> 423<span class="special">};</span> 424</pre> 425<p> 426 We want to measure both the relative error, and the rate of convergence of 427 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>: 428 class test_data will unpack the tuple for us, and create one column of data 429 for each element in the tuple (in addition to the input parameters): 430 </p> 431<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> 432<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> 433<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> 434<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> 435<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> 436 437<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> 438<span class="keyword">struct</span> <span class="identifier">profile_gamma_fraction</span> 439<span class="special">{</span> 440 <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> 441 442 <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> 443 <span class="special">{</span> 444 <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> 445 <span class="comment">// estimate the true value, using arbitrary precision</span> 446 <span class="comment">// arithmetic and NTL::RR:</span> 447 <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> 448 <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> 449 <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> 450 <span class="comment">//</span> 451 <span class="comment">// Now get the approximation at double precision, along with the number of</span> 452 <span class="comment">// iterations required:</span> 453 <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> 454 <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> 455 <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> 456 <span class="comment">//</span> 457 <span class="comment">// Work out the relative error, as measured in units of epsilon:</span> 458 <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> 459 <span class="comment">//</span> 460 <span class="comment">// now just return the results as a tuple:</span> 461 <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> 462 <span class="special">}</span> 463<span class="special">};</span> 464</pre> 465<p> 466 Feeding that functor into test_data allows rapid output of csv data, for 467 whatever type <code class="computeroutput"><span class="identifier">T</span></code> we may be 468 interested in: 469 </p> 470<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> 471<span class="special">{</span> 472 <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> 473 <span class="comment">// create an object to hold the data:</span> 474 <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> 475 <span class="comment">// insert 500 points at uniform intervals between just after 0 and 100:</span> 476 <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> 477 <span class="comment">// print out in csv format:</span> 478 <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> 479 <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> 480<span class="special">}</span> 481</pre> 482<p> 483 This time there's no need to plot a graph, the first few rows are: 484 </p> 485<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> 486 487<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> 488<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> 489<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> 490<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> 491<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> 492<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> 493</pre> 494<p> 495 So it's pretty clear that this fraction shouldn't be used for small values 496 of <span class="emphasis"><em>a</em></span> and <span class="emphasis"><em>z</em></span>. 497 </p> 498<h5> 499<a name="math_toolkit.internals.test_data.h5"></a> 500 <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> 501 </h5> 502<p> 503 Most of this tool has been described already in the examples above, we'll 504 just add the following notes on the non-member functions: 505 </p> 506<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> 507<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> 508</pre> 509<p> 510 Tells class test_data to test <span class="emphasis"><em>n_points</em></span> random values 511 in the range [start_range,end_range]. 512 </p> 513<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> 514<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> 515</pre> 516<p> 517 Tells class test_data to test <span class="emphasis"><em>n_points</em></span> evenly spaced 518 values in the range [start_range,end_range]. 519 </p> 520<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> 521<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> 522</pre> 523<p> 524 Tells class test_data to test points of the form <span class="emphasis"><em>basis + R * 2<sup>expon</sup></em></span> 525 for each <span class="emphasis"><em>expon</em></span> in the range [start_exponent, end_exponent], 526 and <span class="emphasis"><em>R</em></span> a random number in [0.5, 1]. 527 </p> 528<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> 529<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> 530</pre> 531<p> 532 Prompts the user for the parameter range and form to use. 533 </p> 534<p> 535 Finally, if we don't want the parameter to be included in the output, we 536 can tell test_data by setting it a "dummy parameter": 537 </p> 538<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> 539<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> 540</pre> 541<p> 542 This is useful when the functor used transforms the parameter in some way 543 before passing it to the function under test, usually the functor will then 544 return both the transformed input and the result in a tuple, so there's no 545 need for the original pseudo-parameter to be included in program output. 546 </p> 547</div> 548<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 549<td align="left"></td> 550<td align="right"><div class="copyright-footer">Copyright © 2006-2019 Nikhar 551 Agrawal, Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, 552 Hubert Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Matthew Pulver, Johan 553 Råde, Gautam Sewani, Benjamin Sobotta, Nicholas Thompson, Thijs van den Berg, 554 Daryle Walker and Xiaogang Zhang<p> 555 Distributed under the Boost Software License, Version 1.0. (See accompanying 556 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>) 557 </p> 558</div></td> 559</tr></table> 560<hr> 561<div class="spirit-nav"> 562<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> 563</div> 564</body> 565</html> 566