annotate libphobos/src/std/mathspecial.d @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1 // Written in the D programming language.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
4 * Mathematical Special Functions
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
5 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
6 * The technical term 'Special Functions' includes several families of
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
7 * transcendental functions, which have important applications in particular
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
8 * branches of mathematics and physics.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
9 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
10 * The gamma and related functions, and the error function are crucial for
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
11 * mathematical statistics.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
12 * The Bessel and related functions arise in problems involving wave propagation
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
13 * (especially in optics).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
14 * Other major categories of special functions include the elliptic integrals
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
15 * (related to the arc length of an ellipse), and the hypergeometric functions.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
16 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
17 * Status:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
18 * Many more functions will be added to this module.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
19 * The naming convention for the distribution functions (gammaIncomplete, etc)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
20 * is not yet finalized and will probably change.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
21 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
22 * Macros:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
23 * TABLE_SV = <table border="1" cellpadding="4" cellspacing="0">
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
24 * <caption>Special Values</caption>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
25 * $0</table>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
26 * SVH = $(TR $(TH $1) $(TH $2))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
27 * SV = $(TR $(TD $1) $(TD $2))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
28 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
29 * NAN = $(RED NAN)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
30 * SUP = <span style="vertical-align:super;font-size:smaller">$0</span>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
31 * GAMMA = &#915;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
32 * THETA = &theta;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
33 * INTEGRAL = &#8747;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
34 * INTEGRATE = $(BIG &#8747;<sub>$(SMALL $1)</sub><sup>$2</sup>)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
35 * POWER = $1<sup>$2</sup>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
36 * SUB = $1<sub>$2</sub>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
37 * BIGSUM = $(BIG &Sigma; <sup>$2</sup><sub>$(SMALL $1)</sub>)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
38 * CHOOSE = $(BIG &#40;) <sup>$(SMALL $1)</sup><sub>$(SMALL $2)</sub> $(BIG &#41;)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
39 * PLUSMN = &plusmn;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
40 * INFIN = &infin;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
41 * PLUSMNINF = &plusmn;&infin;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
42 * PI = &pi;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
43 * LT = &lt;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
44 * GT = &gt;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
45 * SQRT = &radic;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
46 * HALF = &frac12;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
47 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
48 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
49 * Copyright: Based on the CEPHES math library, which is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
50 * Copyright (C) 1994 Stephen L. Moshier (moshier@world.std.com).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
51 * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
52 * Authors: Stephen L. Moshier (original C code). Conversion to D by Don Clugston
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
53 * Source: $(PHOBOSSRC std/_mathspecial.d)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
54 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
55 module std.mathspecial;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
56 import std.internal.math.errorfunction;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
57 import std.internal.math.gammafunction;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
58 public import std.math;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
59
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
60 /* ***********************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
61 * GAMMA AND RELATED FUNCTIONS *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
62 * ***********************************************/
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
63
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
64 pure:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
65 nothrow:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
66 @safe:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
67 @nogc:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
68
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
69 /** The Gamma function, $(GAMMA)(x)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
70 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
71 * $(GAMMA)(x) is a generalisation of the factorial function
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
72 * to real and complex numbers.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
73 * Like x!, $(GAMMA)(x+1) = x * $(GAMMA)(x).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
74 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
75 * Mathematically, if z.re > 0 then
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
76 * $(GAMMA)(z) = $(INTEGRATE 0, $(INFIN)) $(POWER t, z-1)$(POWER e, -t) dt
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
77 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
78 * $(TABLE_SV
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
79 * $(SVH x, $(GAMMA)(x) )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
80 * $(SV $(NAN), $(NAN) )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
81 * $(SV $(PLUSMN)0.0, $(PLUSMNINF))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
82 * $(SV integer > 0, (x-1)! )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
83 * $(SV integer < 0, $(NAN) )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
84 * $(SV +$(INFIN), +$(INFIN) )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
85 * $(SV -$(INFIN), $(NAN) )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
86 * )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
87 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
88 real gamma(real x)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
89 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
90 return std.internal.math.gammafunction.gamma(x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
91 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
92
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
93 /** Natural logarithm of the gamma function, $(GAMMA)(x)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
94 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
95 * Returns the base e (2.718...) logarithm of the absolute
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
96 * value of the gamma function of the argument.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
97 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
98 * For reals, logGamma is equivalent to log(fabs(gamma(x))).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
99 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
100 * $(TABLE_SV
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
101 * $(SVH x, logGamma(x) )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
102 * $(SV $(NAN), $(NAN) )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
103 * $(SV integer <= 0, +$(INFIN) )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
104 * $(SV $(PLUSMNINF), +$(INFIN) )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
105 * )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
106 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
107 real logGamma(real x)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
108 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
109 return std.internal.math.gammafunction.logGamma(x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
110 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
111
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
112 /** The sign of $(GAMMA)(x).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
113 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
114 * Returns -1 if $(GAMMA)(x) < 0, +1 if $(GAMMA)(x) > 0,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
115 * $(NAN) if sign is indeterminate.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
116 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
117 * Note that this function can be used in conjunction with logGamma(x) to
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
118 * evaluate gamma for very large values of x.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
119 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
120 real sgnGamma(real x)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
121 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
122 /* Author: Don Clugston. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
123 if (isNaN(x)) return x;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
124 if (x > 0) return 1.0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
125 if (x < -1/real.epsilon)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
126 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
127 // Large negatives lose all precision
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
128 return real.nan;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
129 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
130 long n = rndtol(x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
131 if (x == n)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
132 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
133 return x == 0 ? copysign(1, x) : real.nan;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
134 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
135 return n & 1 ? 1.0 : -1.0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
136 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
137
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
138 @safe unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
139 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
140 assert(sgnGamma(5.0) == 1.0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
141 assert(isNaN(sgnGamma(-3.0)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
142 assert(sgnGamma(-0.1) == -1.0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
143 assert(sgnGamma(-55.1) == 1.0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
144 assert(isNaN(sgnGamma(-real.infinity)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
145 assert(isIdentical(sgnGamma(NaN(0xABC)), NaN(0xABC)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
146 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
147
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
148 /** Beta function
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
149 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
150 * The beta function is defined as
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
151 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
152 * beta(x, y) = ($(GAMMA)(x) * $(GAMMA)(y)) / $(GAMMA)(x + y)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
153 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
154 real beta(real x, real y)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
155 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
156 if ((x+y)> MAXGAMMA)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
157 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
158 return exp(logGamma(x) + logGamma(y) - logGamma(x+y));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
159 } else return gamma(x) * gamma(y) / gamma(x+y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
160 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
161
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
162 @safe unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
163 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
164 assert(isIdentical(beta(NaN(0xABC), 4), NaN(0xABC)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
165 assert(isIdentical(beta(2, NaN(0xABC)), NaN(0xABC)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
166 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
167
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
168 /** Digamma function
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
169 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
170 * The digamma function is the logarithmic derivative of the gamma function.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
171 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
172 * digamma(x) = d/dx logGamma(x)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
173 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
174 * See_Also: $(LREF logmdigamma), $(LREF logmdigammaInverse).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
175 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
176 real digamma(real x)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
177 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
178 return std.internal.math.gammafunction.digamma(x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
179 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
180
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
181 /** Log Minus Digamma function
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
182 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
183 * logmdigamma(x) = log(x) - digamma(x)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
184 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
185 * See_Also: $(LREF digamma), $(LREF logmdigammaInverse).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
186 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
187 real logmdigamma(real x)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
188 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
189 return std.internal.math.gammafunction.logmdigamma(x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
190 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
191
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
192 /** Inverse of the Log Minus Digamma function
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
193 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
194 * Given y, the function finds x such log(x) - digamma(x) = y.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
195 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
196 * See_Also: $(LREF logmdigamma), $(LREF digamma).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
197 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
198 real logmdigammaInverse(real x)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
199 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
200 return std.internal.math.gammafunction.logmdigammaInverse(x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
201 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
202
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
203 /** Incomplete beta integral
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
204 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
205 * Returns incomplete beta integral of the arguments, evaluated
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
206 * from zero to x. The regularized incomplete beta function is defined as
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
207 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
208 * betaIncomplete(a, b, x) = $(GAMMA)(a + b) / ( $(GAMMA)(a) $(GAMMA)(b) ) *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
209 * $(INTEGRATE 0, x) $(POWER t, a-1)$(POWER (1-t), b-1) dt
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
210 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
211 * and is the same as the the cumulative distribution function.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
212 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
213 * The domain of definition is 0 <= x <= 1. In this
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
214 * implementation a and b are restricted to positive values.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
215 * The integral from x to 1 may be obtained by the symmetry
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
216 * relation
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
217 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
218 * betaIncompleteCompl(a, b, x ) = betaIncomplete( b, a, 1-x )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
219 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
220 * The integral is evaluated by a continued fraction expansion
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
221 * or, when b * x is small, by a power series.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
222 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
223 real betaIncomplete(real a, real b, real x )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
224 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
225 return std.internal.math.gammafunction.betaIncomplete(a, b, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
226 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
227
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
228 /** Inverse of incomplete beta integral
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
229 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
230 * Given y, the function finds x such that
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
231 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
232 * betaIncomplete(a, b, x) == y
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
233 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
234 * Newton iterations or interval halving is used.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
235 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
236 real betaIncompleteInverse(real a, real b, real y )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
237 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
238 return std.internal.math.gammafunction.betaIncompleteInv(a, b, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
239 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
240
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
241 /** Incomplete gamma integral and its complement
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
242 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
243 * These functions are defined by
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
244 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
245 * gammaIncomplete = ( $(INTEGRATE 0, x) $(POWER e, -t) $(POWER t, a-1) dt )/ $(GAMMA)(a)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
246 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
247 * gammaIncompleteCompl(a,x) = 1 - gammaIncomplete(a,x)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
248 * = ($(INTEGRATE x, $(INFIN)) $(POWER e, -t) $(POWER t, a-1) dt )/ $(GAMMA)(a)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
249 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
250 * In this implementation both arguments must be positive.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
251 * The integral is evaluated by either a power series or
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
252 * continued fraction expansion, depending on the relative
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
253 * values of a and x.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
254 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
255 real gammaIncomplete(real a, real x )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
256 in {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
257 assert(x >= 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
258 assert(a > 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
259 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
260 body {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
261 return std.internal.math.gammafunction.gammaIncomplete(a, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
262 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
263
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
264 /** ditto */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
265 real gammaIncompleteCompl(real a, real x )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
266 in {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
267 assert(x >= 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
268 assert(a > 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
269 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
270 body {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
271 return std.internal.math.gammafunction.gammaIncompleteCompl(a, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
272 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
273
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
274 /** Inverse of complemented incomplete gamma integral
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
275 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
276 * Given a and p, the function finds x such that
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
277 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
278 * gammaIncompleteCompl( a, x ) = p.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
279 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
280 real gammaIncompleteComplInverse(real a, real p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
281 in {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
282 assert(p >= 0 && p <= 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
283 assert(a > 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
284 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
285 body {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
286 return std.internal.math.gammafunction.gammaIncompleteComplInv(a, p);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
287 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
288
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
289
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
290 /* ***********************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
291 * ERROR FUNCTIONS & NORMAL DISTRIBUTION *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
292 * ***********************************************/
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
293
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
294 /** Error function
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
295 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
296 * The integral is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
297 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
298 * erf(x) = 2/ $(SQRT)($(PI))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
299 * $(INTEGRATE 0, x) exp( - $(POWER t, 2)) dt
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
300 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
301 * The magnitude of x is limited to about 106.56 for IEEE 80-bit
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
302 * arithmetic; 1 or -1 is returned outside this range.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
303 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
304 real erf(real x)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
305 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
306 return std.internal.math.errorfunction.erf(x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
307 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
308
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
309 /** Complementary error function
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
310 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
311 * erfc(x) = 1 - erf(x)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
312 * = 2/ $(SQRT)($(PI))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
313 * $(INTEGRATE x, $(INFIN)) exp( - $(POWER t, 2)) dt
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
314 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
315 * This function has high relative accuracy for
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
316 * values of x far from zero. (For values near zero, use erf(x)).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
317 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
318 real erfc(real x)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
319 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
320 return std.internal.math.errorfunction.erfc(x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
321 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
322
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
323
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
324 /** Normal distribution function.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
325 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
326 * The normal (or Gaussian, or bell-shaped) distribution is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
327 * defined as:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
328 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
329 * normalDist(x) = 1/$(SQRT)(2$(PI)) $(INTEGRATE -$(INFIN), x) exp( - $(POWER t, 2)/2) dt
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
330 * = 0.5 + 0.5 * erf(x/sqrt(2))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
331 * = 0.5 * erfc(- x/sqrt(2))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
332 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
333 * To maintain accuracy at values of x near 1.0, use
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
334 * normalDistribution(x) = 1.0 - normalDistribution(-x).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
335 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
336 * References:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
337 * $(LINK http://www.netlib.org/cephes/ldoubdoc.html),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
338 * G. Marsaglia, "Evaluating the Normal Distribution",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
339 * Journal of Statistical Software <b>11</b>, (July 2004).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
340 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
341 real normalDistribution(real x)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
342 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
343 return std.internal.math.errorfunction.normalDistributionImpl(x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
344 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
345
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
346 /** Inverse of Normal distribution function
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
347 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
348 * Returns the argument, x, for which the area under the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
349 * Normal probability density function (integrated from
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
350 * minus infinity to x) is equal to p.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
351 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
352 * Note: This function is only implemented to 80 bit precision.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
353 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
354 real normalDistributionInverse(real p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
355 in {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
356 assert(p >= 0.0L && p <= 1.0L, "Domain error");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
357 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
358 body
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
359 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
360 return std.internal.math.errorfunction.normalDistributionInvImpl(p);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
361 }