summaryrefslogtreecommitdiff
path: root/libs/math/doc/html/math_toolkit/sf_erf/error_inv.html
blob: 1848da903af1d3e3e3dfb3847f07c0163fa41765 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Error Function Inverses</title>
<link rel="stylesheet" href="../../math.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
<link rel="home" href="../../index.html" title="Math Toolkit 2.2.0">
<link rel="up" href="../sf_erf.html" title="Error Functions">
<link rel="prev" href="error_function.html" title="Error Functions">
<link rel="next" href="../sf_poly.html" title="Polynomials">
</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_function.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../sf_erf.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="../sf_poly.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.sf_erf.error_inv"></a><a class="link" href="error_inv.html" title="Error Function Inverses">Error Function Inverses</a>
</h3></div></div></div>
<h5>
<a name="math_toolkit.sf_erf.error_inv.h0"></a>
        <span class="phrase"><a name="math_toolkit.sf_erf.error_inv.synopsis"></a></span><a class="link" href="error_inv.html#math_toolkit.sf_erf.error_inv.synopsis">Synopsis</a>
      </h5>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">special_functions</span><span class="special">/</span><span class="identifier">erf</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">math</span><span class="special">{</span>

<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<a class="link" href="../result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">erf_inv</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">p</span><span class="special">);</span>

<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <a class="link" href="../../policy.html" title="Chapter&#160;14.&#160;Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&gt;</span>
<a class="link" href="../result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">erf_inv</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">p</span><span class="special">,</span> <span class="keyword">const</span> <a class="link" href="../../policy.html" title="Chapter&#160;14.&#160;Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&amp;);</span>

<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<a class="link" href="../result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">erfc_inv</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">p</span><span class="special">);</span>

<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <a class="link" href="../../policy.html" title="Chapter&#160;14.&#160;Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&gt;</span>
<a class="link" href="../result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">erfc_inv</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">p</span><span class="special">,</span> <span class="keyword">const</span> <a class="link" href="../../policy.html" title="Chapter&#160;14.&#160;Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&amp;);</span>

<span class="special">}}</span> <span class="comment">// namespaces</span>
</pre>
<p>
        The return type of these functions is computed using the <a class="link" href="../result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>result
        type calculation rules</em></span></a>: the return type is <code class="computeroutput"><span class="keyword">double</span></code> if T is an integer type, and T otherwise.
      </p>
<p>
        The final <a class="link" href="../../policy.html" title="Chapter&#160;14.&#160;Policies: Controlling Precision, Error Handling etc">Policy</a> argument is optional and can
        be used to control the behaviour of the function: how it handles errors,
        what level of precision to use etc. Refer to the <a class="link" href="../../policy.html" title="Chapter&#160;14.&#160;Policies: Controlling Precision, Error Handling etc">policy
        documentation for more details</a>.
      </p>
<h5>
<a name="math_toolkit.sf_erf.error_inv.h1"></a>
        <span class="phrase"><a name="math_toolkit.sf_erf.error_inv.description"></a></span><a class="link" href="error_inv.html#math_toolkit.sf_erf.error_inv.description">Description</a>
      </h5>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<a class="link" href="../result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">erf_inv</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">z</span><span class="special">);</span>

<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <a class="link" href="../../policy.html" title="Chapter&#160;14.&#160;Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&gt;</span>
<a class="link" href="../result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">erf_inv</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">z</span><span class="special">,</span> <span class="keyword">const</span> <a class="link" href="../../policy.html" title="Chapter&#160;14.&#160;Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&amp;);</span>
</pre>
<p>
        Returns the <a href="http://functions.wolfram.com/GammaBetaErf/InverseErf/" target="_top">inverse
        error function</a> of z, that is a value x such that:
      </p>
<pre class="programlisting"><span class="identifier">p</span> <span class="special">=</span> <span class="identifier">erf</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
</pre>
<p>
        <span class="inlinemediaobject"><img src="../../../graphs/erf_inv.svg" align="middle"></span>
      </p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<a class="link" href="../result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">erfc_inv</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">z</span><span class="special">);</span>

<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <a class="link" href="../../policy.html" title="Chapter&#160;14.&#160;Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&gt;</span>
<a class="link" href="../result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">erfc_inv</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">z</span><span class="special">,</span> <span class="keyword">const</span> <a class="link" href="../../policy.html" title="Chapter&#160;14.&#160;Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&amp;);</span>
</pre>
<p>
        Returns the inverse of the complement of the error function of z, that is
        a value x such that:
      </p>
<pre class="programlisting"><span class="identifier">p</span> <span class="special">=</span> <span class="identifier">erfc</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
</pre>
<p>
        <span class="inlinemediaobject"><img src="../../../graphs/erfc_inv.svg" align="middle"></span>
      </p>
<h5>
<a name="math_toolkit.sf_erf.error_inv.h2"></a>
        <span class="phrase"><a name="math_toolkit.sf_erf.error_inv.accuracy"></a></span><a class="link" href="error_inv.html#math_toolkit.sf_erf.error_inv.accuracy">Accuracy</a>
      </h5>
<p>
        For types up to and including 80-bit long doubles the approximations used
        are accurate to less than ~ 2 epsilon. For higher precision types these functions
        have the same accuracy as the <a class="link" href="error_function.html" title="Error Functions">forward
        error functions</a>.
      </p>
<h5>
<a name="math_toolkit.sf_erf.error_inv.h3"></a>
        <span class="phrase"><a name="math_toolkit.sf_erf.error_inv.testing"></a></span><a class="link" href="error_inv.html#math_toolkit.sf_erf.error_inv.testing">Testing</a>
      </h5>
<p>
        There are two sets of tests:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            Basic sanity checks attempt to "round-trip" from <span class="emphasis"><em>x</em></span>
            to <span class="emphasis"><em>p</em></span> and back again. These tests have quite generous
            tolerances: in general both the error functions and their inverses change
            so rapidly in some places that round tripping to more than a couple of
            significant digits isn't possible. This is especially true when <span class="emphasis"><em>p</em></span>
            is very near one: in this case there isn't enough "information content"
            in the input to the inverse function to get back where you started.
          </li>
<li class="listitem">
            Accuracy checks using high-precision test values. These measure the accuracy
            of the result, given <span class="emphasis"><em>exact</em></span> input values.
          </li>
</ul></div>
<h5>
<a name="math_toolkit.sf_erf.error_inv.h4"></a>
        <span class="phrase"><a name="math_toolkit.sf_erf.error_inv.implementation"></a></span><a class="link" href="error_inv.html#math_toolkit.sf_erf.error_inv.implementation">Implementation</a>
      </h5>
<p>
        These functions use a rational approximation <a class="link" href="../sf_implementation.html#math_toolkit.sf_implementation.rational_approximations_used">devised
        by JM</a> to calculate an initial approximation to the result that is
        accurate to ~10<sup>-19</sup>, then only if that has insufficient accuracy compared
        to the epsilon for T, do we clean up the result using <a href="http://en.wikipedia.org/wiki/Simple_rational_approximation" target="_top">Halley
        iteration</a>.
      </p>
<p>
        Constructing rational approximations to the erf/erfc functions is actually
        surprisingly hard, especially at high precision. For this reason no attempt
        has been made to achieve 10<sup>-34 </sup> accuracy suitable for use with 128-bit reals.
      </p>
<p>
        In the following discussion, <span class="emphasis"><em>p</em></span> is the value passed to
        erf_inv, and <span class="emphasis"><em>q</em></span> is the value passed to erfc_inv, so that
        <span class="emphasis"><em>p = 1 - q</em></span> and <span class="emphasis"><em>q = 1 - p</em></span> and in
        both cases we want to solve for the same result <span class="emphasis"><em>x</em></span>.
      </p>
<p>
        For <span class="emphasis"><em>p &lt; 0.5</em></span> the inverse erf function is reasonably
        smooth and the approximation:
      </p>
<pre class="programlisting"><span class="identifier">x</span> <span class="special">=</span> <span class="identifier">p</span><span class="special">(</span><span class="identifier">p</span> <span class="special">+</span> <span class="number">10</span><span class="special">)(</span><span class="identifier">Y</span> <span class="special">+</span> <span class="identifier">R</span><span class="special">(</span><span class="identifier">p</span><span class="special">))</span>
</pre>
<p>
        Gives a good result for a constant Y, and R(p) optimised for low absolute
        error compared to |Y|.
      </p>
<p>
        For q &lt; 0.5 things get trickier, over the interval <span class="emphasis"><em>0.5 &gt;
        q &gt; 0.25</em></span> the following approximation works well:
      </p>
<pre class="programlisting"><span class="identifier">x</span> <span class="special">=</span> <span class="identifier">sqrt</span><span class="special">(-</span><span class="number">2l</span><span class="identifier">og</span><span class="special">(</span><span class="identifier">q</span><span class="special">))</span> <span class="special">/</span> <span class="special">(</span><span class="identifier">Y</span> <span class="special">+</span> <span class="identifier">R</span><span class="special">(</span><span class="identifier">q</span><span class="special">))</span>
</pre>
<p>
        While for q &lt; 0.25, let
      </p>
<pre class="programlisting"><span class="identifier">z</span> <span class="special">=</span> <span class="identifier">sqrt</span><span class="special">(-</span><span class="identifier">log</span><span class="special">(</span><span class="identifier">q</span><span class="special">))</span>
</pre>
<p>
        Then the result is given by:
      </p>
<pre class="programlisting"><span class="identifier">x</span> <span class="special">=</span> <span class="identifier">z</span><span class="special">(</span><span class="identifier">Y</span> <span class="special">+</span> <span class="identifier">R</span><span class="special">(</span><span class="identifier">z</span> <span class="special">-</span> <span class="identifier">B</span><span class="special">))</span>
</pre>
<p>
        As before Y is a constant and the rational function R is optimised for low
        absolute error compared to |Y|. B is also a constant: it is the smallest
        value of <span class="emphasis"><em>z</em></span> for which each approximation is valid. There
        are several approximations of this form each of which reaches a little further
        into the tail of the erfc function (at <code class="computeroutput"><span class="keyword">long</span>
        <span class="keyword">double</span></code> precision the extended exponent
        range compared to <code class="computeroutput"><span class="keyword">double</span></code> means
        that the tail goes on for a very long way indeed).
      </p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2006-2010, 2012-2014 Nikhar Agrawal,
      Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
      Holin, Bruno Lalande, John Maddock, Johan R&#229;de, Gautam Sewani, Benjamin Sobotta,
      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_function.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../sf_erf.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="../sf_poly.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>