rubystats 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +7 -0
- data/Manifest.txt +22 -0
- data/README.txt +109 -0
- data/Rakefile +19 -0
- data/examples/beta.rb +10 -12
- data/examples/binomial.rb +12 -10
- data/examples/failrate_vs_goal.rb +28 -0
- data/examples/fisher.rb +2 -6
- data/examples/norm.rb +10 -4
- data/lib/rubystats.rb +9 -0
- data/lib/rubystats/beta_distribution.rb +88 -0
- data/lib/rubystats/binomial_distribution.rb +195 -0
- data/lib/rubystats/fishers_exact_test.rb +171 -0
- data/lib/rubystats/modules.rb +742 -0
- data/lib/rubystats/normal_distribution.rb +114 -0
- data/lib/rubystats/probability_distribution.rb +131 -0
- data/{tests → test}/tc_beta.rb +4 -4
- data/{tests → test}/tc_binomial.rb +4 -4
- data/{tests → test}/tc_fisher.rb +2 -2
- data/test/tc_norm.rb +14 -0
- data/test/tc_require_all.rb +18 -0
- data/{tests → test}/ts_stats.rb +0 -0
- metadata +72 -51
- data/README +0 -9
- data/lib/beta_distribution.rb +0 -87
- data/lib/binomial_distribution.rb +0 -194
- data/lib/fishers_exact_test.rb +0 -171
- data/lib/modules/extra_math.rb +0 -7
- data/lib/modules/numerical_constants.rb +0 -17
- data/lib/modules/special_math.rb +0 -721
- data/lib/normal_distribution.rb +0 -114
- data/lib/probability_distribution.rb +0 -132
- data/tests/tc_norm.rb +0 -13
data/lib/modules/extra_math.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
module NumericalConstants
|
2
|
-
Max_float = 3.40282346638528860e292
|
3
|
-
Eps = 2.22e-16
|
4
|
-
Max_value = 1.2e290
|
5
|
-
Log_gamma_x_max_value = 2.55e292
|
6
|
-
Gamma_x_max_value = 171.624
|
7
|
-
Sqrt2pi = 2.5066282746310005024157652848110452530069867406099
|
8
|
-
Sqrt2 = 1.4142135623730950488016887242096980785696718753769
|
9
|
-
Xminin = 2.23e-303
|
10
|
-
Max_iterations = 1000
|
11
|
-
Precision = 8.88e-016
|
12
|
-
Two_pi = 6.2831853071795864769252867665590057683943387987502
|
13
|
-
Gamma = 0.57721566490153286060651209008240243104215933593992
|
14
|
-
Golden_ratio = 1.6180339887498948482045868343656381177203091798058
|
15
|
-
end
|
16
|
-
|
17
|
-
|
data/lib/modules/special_math.rb
DELETED
@@ -1,721 +0,0 @@
|
|
1
|
-
require 'modules/numerical_constants'
|
2
|
-
|
3
|
-
# Ruby port of SpecialMath.php from PHPMath, which is
|
4
|
-
# a port of JSci methods found in SpecialMath.java.
|
5
|
-
#
|
6
|
-
#
|
7
|
-
# Ruby port by Bryan Donovan Bryan.Donovan@sun.com
|
8
|
-
#
|
9
|
-
# Author:: Jaco van Kooten
|
10
|
-
# Author:: Paul Meagher
|
11
|
-
# Author:: Bryan Donovan
|
12
|
-
|
13
|
-
module SpecialMath
|
14
|
-
|
15
|
-
include NumericalConstants
|
16
|
-
|
17
|
-
@logGammaCache_res = 0.0
|
18
|
-
@logGammaCache_x = 0.0
|
19
|
-
@logBetaCache_res = 0.0
|
20
|
-
@logBetaCache_p = 0.0
|
21
|
-
@logBetaCache_q = 0.0
|
22
|
-
|
23
|
-
|
24
|
-
def log_beta(p,q)
|
25
|
-
if p != @logBetaCache_p || q != @logBetaCache_q
|
26
|
-
logBetaCache_p = p
|
27
|
-
logBetaCache_q = q
|
28
|
-
if p <= 0.0 || q <= 0.0 || (p + q) > Log_gamma_x_max_value
|
29
|
-
logBetaCache_res = 0.0
|
30
|
-
else
|
31
|
-
logBetaCache_res = log_gamma(p) + log_gamma(q) - log_gamma(p + q)
|
32
|
-
end
|
33
|
-
return logBetaCache_res
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
# Gamma function.
|
38
|
-
# Based on public domain NETLIB (Fortran) code by W. J. Cody and L. Stoltz<BR>
|
39
|
-
# Applied Mathematics Division<BR>
|
40
|
-
# Argonne National Laboratory<BR>
|
41
|
-
# Argonne, IL 60439<BR>
|
42
|
-
# <P>
|
43
|
-
# References:
|
44
|
-
# <OL>
|
45
|
-
# <LI>"An Overview of Software Development for Special Functions", W. J. Cody, Lecture Notes in Mathematics, 506, Numerical Analysis Dundee, 1975, G. A. Watson (ed.), Springer Verlag, Berlin, 1976.
|
46
|
-
# <LI>Computer Approximations, Hart, Et. Al., Wiley and sons, New York, 1968.
|
47
|
-
# </OL></P><P>
|
48
|
-
# From the original documentation:
|
49
|
-
# </P><P>
|
50
|
-
# This routine calculates the GAMMA function for a real argument X.
|
51
|
-
# Computation is based on an algorithm outlined in reference 1.
|
52
|
-
# The program uses rational functions that approximate the GAMMA
|
53
|
-
# function to at least 20 significant decimal digits. Coefficients
|
54
|
-
# for the approximation over the interval (1,2) are unpublished.
|
55
|
-
# Those for the approximation for X .GE. 12 are from reference 2.
|
56
|
-
# The accuracy achieved depends on the arithmetic system, the
|
57
|
-
# compiler, the intrinsic functions, and proper selection of the
|
58
|
-
# machine-dependent constants.
|
59
|
-
# </P><P>
|
60
|
-
# Error returns:<BR>
|
61
|
-
# The program returns the value XINF for singularities or when overflow would occur.
|
62
|
-
# The computation is believed to be free of underflow and overflow.
|
63
|
-
# </P>
|
64
|
-
# Author:: Jaco van Kooten
|
65
|
-
|
66
|
-
def gamma(x)
|
67
|
-
# gamma related constants
|
68
|
-
g_p = [ -1.71618513886549492533811, 24.7656508055759199108314,
|
69
|
-
-379.804256470945635097577, 629.331155312818442661052,
|
70
|
-
866.966202790413211295064, -31451.2729688483675254357,
|
71
|
-
-36144.4134186911729807069, 66456.1438202405440627855 ]
|
72
|
-
g_q = [-30.8402300119738975254353, 315.350626979604161529144,
|
73
|
-
-1015.15636749021914166146, -3107.77167157231109440444,
|
74
|
-
22538.1184209801510330112, 4755.84627752788110767815,
|
75
|
-
-134659.959864969306392456, -115132.259675553483497211 ]
|
76
|
-
g_c = [-0.001910444077728, 8.4171387781295e-4, -5.952379913043012e-4,
|
77
|
-
7.93650793500350248e-4, -0.002777777777777681622553,
|
78
|
-
0.08333333333333333331554247, 0.0057083835261 ]
|
79
|
-
fact=1.0
|
80
|
-
i=0
|
81
|
-
n=0
|
82
|
-
y=x
|
83
|
-
parity=false
|
84
|
-
if y <= 0.0
|
85
|
-
# ----------------------------------------------------------------------
|
86
|
-
# Argument is negative
|
87
|
-
# ----------------------------------------------------------------------
|
88
|
-
y = -(x)
|
89
|
-
y1 = y.to_i
|
90
|
-
res = y - y1
|
91
|
-
if res != 0.0
|
92
|
-
if y1 != (((y1*0.5).to_i) * 2.0)
|
93
|
-
parity = true
|
94
|
-
fact = -M_pi/sin(M_pi * res)
|
95
|
-
y += 1
|
96
|
-
end
|
97
|
-
else
|
98
|
-
return Max_value
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
# ----------------------------------------------------------------------
|
103
|
-
# Argument is positive
|
104
|
-
# ----------------------------------------------------------------------
|
105
|
-
if y < Eps
|
106
|
-
# ----------------------------------------------------------------------
|
107
|
-
# Argument .LT. EPS
|
108
|
-
# ----------------------------------------------------------------------
|
109
|
-
if y >= Xminin
|
110
|
-
res = 1.0 / y
|
111
|
-
else
|
112
|
-
return Max_value
|
113
|
-
end
|
114
|
-
elsif y < 12.0
|
115
|
-
y1 = y
|
116
|
-
#end
|
117
|
-
if y < 1.0
|
118
|
-
# ----------------------------------------------------------------------
|
119
|
-
# 0.0 .LT. argument .LT. 1.0
|
120
|
-
# ----------------------------------------------------------------------
|
121
|
-
z = y
|
122
|
-
y += 1
|
123
|
-
else
|
124
|
-
# ----------------------------------------------------------------------
|
125
|
-
# 1.0 .LT. argument .LT. 12.0, reduce argument if necessary
|
126
|
-
# ----------------------------------------------------------------------
|
127
|
-
n = y.to_i - 1
|
128
|
-
y -= n.to_f
|
129
|
-
z = y - 1.0
|
130
|
-
end
|
131
|
-
# ----------------------------------------------------------------------
|
132
|
-
# Evaluate approximation for 1.0 .LT. argument .LT. 2.0
|
133
|
-
# ----------------------------------------------------------------------
|
134
|
-
xnum = 0.0
|
135
|
-
xden = 1.0
|
136
|
-
for i in (0...8)
|
137
|
-
xnum = (xnum + g_p[i]) * z
|
138
|
-
xden = xden * z + g_q[i]
|
139
|
-
end
|
140
|
-
res = xnum / xden + 1.0
|
141
|
-
if y1 < y
|
142
|
-
# ----------------------------------------------------------------------
|
143
|
-
# Adjust result for case 0.0 .LT. argument .LT. 1.0
|
144
|
-
# ----------------------------------------------------------------------
|
145
|
-
res /= y1
|
146
|
-
elsif y1 > y
|
147
|
-
# ----------------------------------------------------------------------
|
148
|
-
# Adjust result for case 2.0 .LT. argument .LT. 12.0
|
149
|
-
# ----------------------------------------------------------------------
|
150
|
-
for i in (0...n)
|
151
|
-
res *= y
|
152
|
-
y += 1
|
153
|
-
end
|
154
|
-
end
|
155
|
-
else
|
156
|
-
# ----------------------------------------------------------------------
|
157
|
-
# Evaluate for argument .GE. 12.0
|
158
|
-
# ----------------------------------------------------------------------
|
159
|
-
if y <= Gamma_x_max_value
|
160
|
-
ysq = y * y
|
161
|
-
sum = g_c[6]
|
162
|
-
for i in(0...6)
|
163
|
-
sum = sum / ysq + g_c[i]
|
164
|
-
sum = sum / y - y + log(sqrt2pi)
|
165
|
-
sum += (y - 0.5) * log(y)
|
166
|
-
res = Math.exp(sum)
|
167
|
-
end
|
168
|
-
else
|
169
|
-
return Max_value
|
170
|
-
end
|
171
|
-
# ----------------------------------------------------------------------
|
172
|
-
# Final adjustments and return
|
173
|
-
# ----------------------------------------------------------------------
|
174
|
-
if parity
|
175
|
-
res = -res
|
176
|
-
if fact != 1.0
|
177
|
-
res = fact / res
|
178
|
-
return res
|
179
|
-
end
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
def log_gamma(x)
|
185
|
-
logGammaCache_res = @logGammaCache_res
|
186
|
-
logGammaCache_x = @logGammaCache_x
|
187
|
-
|
188
|
-
lg_d1 = -0.5772156649015328605195174
|
189
|
-
lg_d2 = 0.4227843350984671393993777
|
190
|
-
lg_d4 = 1.791759469228055000094023
|
191
|
-
|
192
|
-
lg_p1 = [ 4.945235359296727046734888,
|
193
|
-
201.8112620856775083915565, 2290.838373831346393026739,
|
194
|
-
11319.67205903380828685045, 28557.24635671635335736389,
|
195
|
-
38484.96228443793359990269, 26377.48787624195437963534,
|
196
|
-
7225.813979700288197698961 ]
|
197
|
-
|
198
|
-
lg_p2 = [ 4.974607845568932035012064,
|
199
|
-
542.4138599891070494101986, 15506.93864978364947665077,
|
200
|
-
184793.2904445632425417223, 1088204.76946882876749847,
|
201
|
-
3338152.967987029735917223, 5106661.678927352456275255,
|
202
|
-
3074109.054850539556250927 ]
|
203
|
-
|
204
|
-
lg_p4 = [ 14745.02166059939948905062,
|
205
|
-
2426813.369486704502836312, 121475557.4045093227939592,
|
206
|
-
2663432449.630976949898078, 29403789566.34553899906876,
|
207
|
-
170266573776.5398868392998, 492612579337.743088758812,
|
208
|
-
560625185622.3951465078242 ]
|
209
|
-
|
210
|
-
lg_q1 = [ 67.48212550303777196073036,
|
211
|
-
1113.332393857199323513008, 7738.757056935398733233834,
|
212
|
-
27639.87074403340708898585, 54993.10206226157329794414,
|
213
|
-
61611.22180066002127833352, 36351.27591501940507276287,
|
214
|
-
8785.536302431013170870835 ]
|
215
|
-
|
216
|
-
lg_q2 = [ 183.0328399370592604055942,
|
217
|
-
7765.049321445005871323047, 133190.3827966074194402448,
|
218
|
-
1136705.821321969608938755, 5267964.117437946917577538,
|
219
|
-
13467014.54311101692290052, 17827365.30353274213975932,
|
220
|
-
9533095.591844353613395747 ]
|
221
|
-
|
222
|
-
lg_q4 = [ 2690.530175870899333379843,
|
223
|
-
639388.5654300092398984238, 41355999.30241388052042842,
|
224
|
-
1120872109.61614794137657, 14886137286.78813811542398,
|
225
|
-
101680358627.2438228077304, 341747634550.7377132798597,
|
226
|
-
446315818741.9713286462081 ]
|
227
|
-
|
228
|
-
lg_c = [ -0.001910444077728,8.4171387781295e-4,
|
229
|
-
-5.952379913043012e-4, 7.93650793500350248e-4,
|
230
|
-
-0.002777777777777681622553, 0.08333333333333333331554247,
|
231
|
-
0.0057083835261 ]
|
232
|
-
|
233
|
-
# Rough estimate of the fourth root of logGamma_xBig
|
234
|
-
lg_frtbig = 2.25e76
|
235
|
-
pnt68 = 0.6796875
|
236
|
-
|
237
|
-
if x == logGammaCache_x
|
238
|
-
return logGammaCache_res
|
239
|
-
end
|
240
|
-
|
241
|
-
y = x
|
242
|
-
if y > 0.0 && y <= Log_gamma_x_max_value
|
243
|
-
if y <= Eps
|
244
|
-
res = -Math.log(y)
|
245
|
-
elsif y <= 1.5
|
246
|
-
# EPS .LT. X .LE. 1.5
|
247
|
-
if y < pnt68
|
248
|
-
corr = -Math.log(y)
|
249
|
-
# xm1 is x-m-one, not x-m-L
|
250
|
-
xm1 = y
|
251
|
-
else
|
252
|
-
corr = 0.0
|
253
|
-
xm1 = y - 1.0
|
254
|
-
end
|
255
|
-
if y <= 0.5 || y >= pnt68
|
256
|
-
xden = 1.0
|
257
|
-
xnum = 0.0
|
258
|
-
for i in (0...8)
|
259
|
-
xnum = xnum * xm1 + lg_p1[i]
|
260
|
-
xden = xden * xm1 + lg_q1[i]
|
261
|
-
end
|
262
|
-
res = corr * xm1 * (lg_d1 + xm1 * (xnum / xden))
|
263
|
-
else
|
264
|
-
xm2 = y - 1.0
|
265
|
-
xden = 1.0
|
266
|
-
xnum = 0.0
|
267
|
-
for i in (0 ... 8)
|
268
|
-
xnum = xnum * xm2 + lg_p2[i]
|
269
|
-
xden = xden * xm2 + lg_q2[i]
|
270
|
-
end
|
271
|
-
res = corr + xm2 * (lg_d2 + xm2 * (xnum / xden))
|
272
|
-
end
|
273
|
-
elsif y <= 4.0
|
274
|
-
# 1.5 .LT. X .LE. 4.0
|
275
|
-
xm2 = y - 2.0
|
276
|
-
xden = 1.0
|
277
|
-
xnum = 0.0
|
278
|
-
for i in (0 ... 8)
|
279
|
-
xnum = xnum * xm2 + lg_p2[i]
|
280
|
-
xden = xden * xm2 + lg_q2[i]
|
281
|
-
end
|
282
|
-
res = xm2 * (lg_d2 + xm2 * (xnum / xden))
|
283
|
-
elsif y <= 12.0
|
284
|
-
# 4.0 .LT. X .LE. 12.0
|
285
|
-
xm4 = y - 4.0
|
286
|
-
xden = -1.0
|
287
|
-
xnum = 0.0
|
288
|
-
for i in (0 ... 8)
|
289
|
-
xnum = xnum * xm4 + lg_p4[i]
|
290
|
-
xden = xden * xm4 + lg_q4[i]
|
291
|
-
end
|
292
|
-
res = lg_d4 + xm4 * (xnum / xden)
|
293
|
-
else
|
294
|
-
# Evaluate for argument .GE. 12.0
|
295
|
-
res = 0.0
|
296
|
-
if y <= lg_frtbig
|
297
|
-
res = lg_c[6]
|
298
|
-
ysq = y * y
|
299
|
-
for i in (0...6)
|
300
|
-
res = res / ysq + lg_c[i]
|
301
|
-
end
|
302
|
-
end
|
303
|
-
res = res/y
|
304
|
-
corr = Math.log(y)
|
305
|
-
res = res + Math.log(Sqrt2pi) - 0.5 * corr
|
306
|
-
res = res + y * (corr - 1.0)
|
307
|
-
end
|
308
|
-
else
|
309
|
-
#return for bad arguments
|
310
|
-
res = Max_value
|
311
|
-
end
|
312
|
-
# final adjustments and return
|
313
|
-
logGammaCache_x = x
|
314
|
-
logGammaCache_res = res
|
315
|
-
return res
|
316
|
-
end
|
317
|
-
|
318
|
-
|
319
|
-
# Incomplete gamma function.
|
320
|
-
# The computation is based on approximations presented in
|
321
|
-
# Numerical Recipes, Chapter 6.2 (W.H. Press et al, 1992).
|
322
|
-
# @param a require a>=0
|
323
|
-
# @param x require x>=0
|
324
|
-
# @return 0 if x<0, a<=0 or a>2.55E305 to avoid errors and over/underflow
|
325
|
-
# @author Jaco van Kooten
|
326
|
-
|
327
|
-
def incomplete_gamma(a, x)
|
328
|
-
if x <= 0.0 || a <= 0.0 || a > Log_gamma_x_max_value
|
329
|
-
return 0.0
|
330
|
-
elsif x < (a + 1.0)
|
331
|
-
return gamma_series_expansion(a, x)
|
332
|
-
else
|
333
|
-
return 1.0-gamma_fraction(a, x)
|
334
|
-
end
|
335
|
-
end
|
336
|
-
|
337
|
-
# Author:: Jaco van Kooten
|
338
|
-
def gamma_series_expansion(a, x)
|
339
|
-
ap = a
|
340
|
-
del = 1.0 / a
|
341
|
-
sum = del
|
342
|
-
for n in (1...Max_iterations)
|
343
|
-
ap += 1
|
344
|
-
del *= x / ap
|
345
|
-
sum += del
|
346
|
-
if del < sum * Precision
|
347
|
-
return sum * Math.exp(-x + a * Math.log(x) - log_gamma(a))
|
348
|
-
end
|
349
|
-
end
|
350
|
-
return "Maximum iterations exceeded: please file a bug report."
|
351
|
-
end
|
352
|
-
|
353
|
-
# Author:: Jaco van Kooten
|
354
|
-
def gamma_fraction(a, x)
|
355
|
-
b = x + 1.0 - a
|
356
|
-
c = 1.0 / Xminin
|
357
|
-
d = 1.0 / b
|
358
|
-
h = d
|
359
|
-
del= 0.0
|
360
|
-
an = 0.0
|
361
|
-
for i in (1...Max_iterations)
|
362
|
-
if (del-1.0).abs > Precision
|
363
|
-
an = -i * (i - a)
|
364
|
-
b += 2.0
|
365
|
-
d = an * d + b
|
366
|
-
c = b + an / c
|
367
|
-
if c.abs < Xminin
|
368
|
-
c = Xminin
|
369
|
-
if d.abs < Xminin
|
370
|
-
c = Xminin
|
371
|
-
d = 1.0 / d
|
372
|
-
del = d * c
|
373
|
-
h *= del
|
374
|
-
end
|
375
|
-
end
|
376
|
-
end
|
377
|
-
return Math.exp(-x + a * Math.log(x) - log_gamma(a)) * h
|
378
|
-
end
|
379
|
-
end
|
380
|
-
|
381
|
-
# Beta function.
|
382
|
-
#
|
383
|
-
# Author:: Jaco van Kooten
|
384
|
-
|
385
|
-
def beta(p, q)
|
386
|
-
if p <= 0.0 || q <= 0.0 || (p + q) > Log_gamma_x_max_value
|
387
|
-
return 0.0
|
388
|
-
else
|
389
|
-
return Math.exp(log_beta(p, q))
|
390
|
-
end
|
391
|
-
end
|
392
|
-
|
393
|
-
# Incomplete Beta function.
|
394
|
-
#
|
395
|
-
# Author:: Jaco van Kooten
|
396
|
-
# Author:: Paul Meagher
|
397
|
-
#
|
398
|
-
# The computation is based on formulas from Numerical Recipes,
|
399
|
-
# Chapter 6.4 (W.H. Press et al, 1992).
|
400
|
-
|
401
|
-
def incomplete_beta(x, p, q)
|
402
|
-
if x <= 0.0
|
403
|
-
return 0.0
|
404
|
-
elsif x >= 1.0
|
405
|
-
return 1.0
|
406
|
-
elsif p <= 0.0 || q <= 0.0 || (p + q) > Log_gamma_x_max_value
|
407
|
-
return 0.0
|
408
|
-
else
|
409
|
-
beta_gam = Math.exp( -log_beta(p, q) + p * Math.log(x) + q * Math.log(1.0 - x) )
|
410
|
-
if x < (p + 1.0) / (p + q + 2.0)
|
411
|
-
return beta_gam * beta_fraction(x, p, q) / p
|
412
|
-
else
|
413
|
-
beta_frac = beta_fraction(1.0 - x, p, q)
|
414
|
-
return 1.0 - (beta_gam * beta_fraction(1.0 - x, q, p) / q)
|
415
|
-
end
|
416
|
-
end
|
417
|
-
end
|
418
|
-
|
419
|
-
|
420
|
-
# Evaluates of continued fraction part of incomplete beta function.
|
421
|
-
# Based on an idea from Numerical Recipes (W.H. Press et al, 1992).
|
422
|
-
# Author:: Jaco van Kooten
|
423
|
-
|
424
|
-
def beta_fraction(x, p, q)
|
425
|
-
c = 1.0
|
426
|
-
sum_pq = p + q
|
427
|
-
p_plus = p + 1.0
|
428
|
-
p_minus = p - 1.0
|
429
|
-
h = 1.0 - sum_pq * x / p_plus
|
430
|
-
if h.abs < Xminin
|
431
|
-
h = Xminin
|
432
|
-
end
|
433
|
-
h = 1.0 / h
|
434
|
-
frac = h
|
435
|
-
m = 1
|
436
|
-
delta = 0.0
|
437
|
-
|
438
|
-
while (m <= Max_iterations) && ((delta - 1.0).abs > Precision)
|
439
|
-
m2 = 2 * m
|
440
|
-
# even index for d
|
441
|
-
d = m * (q - m) * x / ( (p_minus + m2) * (p + m2))
|
442
|
-
h = 1.0 + d * h
|
443
|
-
if h.abs < Xminin
|
444
|
-
h = Xminin
|
445
|
-
end
|
446
|
-
h = 1.0 / h
|
447
|
-
c = 1.0 + d / c
|
448
|
-
if c.abs < Xminin
|
449
|
-
c = Xminin
|
450
|
-
end
|
451
|
-
frac *= h * c
|
452
|
-
# odd index for d
|
453
|
-
d = -(p + m) * (sum_pq + m) * x / ((p + m2) * (p_plus + m2))
|
454
|
-
h = 1.0 + d * h
|
455
|
-
if h.abs < Xminin
|
456
|
-
h = Xminin
|
457
|
-
end
|
458
|
-
h = 1.0 / h
|
459
|
-
c = 1.0 + d / c
|
460
|
-
if c.abs < Xminin
|
461
|
-
c = Xminin
|
462
|
-
end
|
463
|
-
delta = h * c
|
464
|
-
frac *= delta
|
465
|
-
m += 1
|
466
|
-
end
|
467
|
-
return frac
|
468
|
-
end
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
# Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
473
|
-
#
|
474
|
-
# Developed at SunSoft, a Sun Microsystems, Inc. business.
|
475
|
-
# Permission to use, copy, modify, and distribute this
|
476
|
-
# software is freely granted, provided that this notice
|
477
|
-
# is preserved.
|
478
|
-
#
|
479
|
-
# x
|
480
|
-
# 2 |\
|
481
|
-
# erf(x) = --------- | exp(-t*t)dt
|
482
|
-
# sqrt(pi) \|
|
483
|
-
# 0
|
484
|
-
#
|
485
|
-
# erfc(x) = 1-erf(x)
|
486
|
-
# Note that
|
487
|
-
# erf(-x) = -erf(x)
|
488
|
-
# erfc(-x) = 2 - erfc(x)
|
489
|
-
#
|
490
|
-
# Method:
|
491
|
-
# 1. For |x| in [0, 0.84375]
|
492
|
-
# erf(x) = x + x*R(x^2)
|
493
|
-
# erfc(x) = 1 - erf(x) if x in [-.84375,0.25]
|
494
|
-
# = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375]
|
495
|
-
# where R = P/Q where P is an odd poly of degree 8 and
|
496
|
-
# Q is an odd poly of degree 10.
|
497
|
-
# -57.90
|
498
|
-
# | R - (erf(x)-x)/x | <= 2
|
499
|
-
#
|
500
|
-
#
|
501
|
-
# Remark. The formula is derived by noting
|
502
|
-
# erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....)
|
503
|
-
# and that
|
504
|
-
# 2/sqrt(pi) = 1.128379167095512573896158903121545171688
|
505
|
-
# is close to one. The interval is chosen because the fix
|
506
|
-
# point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is
|
507
|
-
# near 0.6174), and by some experiment, 0.84375 is chosen to
|
508
|
-
# guarantee the error is less than one ulp for erf.
|
509
|
-
#
|
510
|
-
# 2. For |x| in [0.84375,1.25], let s = |x| - 1, and
|
511
|
-
# c = 0.84506291151 rounded to single (24 bits)
|
512
|
-
# erf(x) = sign(x) * (c + P1(s)/Q1(s))
|
513
|
-
# erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0
|
514
|
-
# 1+(c+P1(s)/Q1(s)) if x < 0
|
515
|
-
# |P1/Q1 - (erf(|x|)-c)| <= 2**-59.06
|
516
|
-
# Remark: here we use the taylor series expansion at x=1.
|
517
|
-
# erf(1+s) = erf(1) + s*Poly(s)
|
518
|
-
# = 0.845.. + P1(s)/Q1(s)
|
519
|
-
# That is, we use rational approximation to approximate
|
520
|
-
# erf(1+s) - (c = (single)0.84506291151)
|
521
|
-
# Note that |P1/Q1|< 0.078 for x in [0.84375,1.25]
|
522
|
-
# where
|
523
|
-
# P1(s) = degree 6 poly in s
|
524
|
-
# Q1(s) = degree 6 poly in s
|
525
|
-
#
|
526
|
-
# 3. For x in [1.25,1/0.35(~2.857143)],
|
527
|
-
# erfc(x) = (1/x)*exp(-x*x-0.5625+R1/S1)
|
528
|
-
# erf(x) = 1 - erfc(x)
|
529
|
-
# where
|
530
|
-
# R1(z) = degree 7 poly in z, (z=1/x^2)
|
531
|
-
# S1(z) = degree 8 poly in z
|
532
|
-
#
|
533
|
-
# 4. For x in [1/0.35,28]
|
534
|
-
# erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0
|
535
|
-
# = 2.0 - (1/x)*exp(-x*x-0.5625+R2/S2) if -6<x<0
|
536
|
-
# = 2.0 - tiny (if x <= -6)
|
537
|
-
# erf(x) = sign(x)*(1.0 - erfc(x)) if x < 6, else
|
538
|
-
# erf(x) = sign(x)*(1.0 - tiny)
|
539
|
-
# where
|
540
|
-
# R2(z) = degree 6 poly in z, (z=1/x^2)
|
541
|
-
# S2(z) = degree 7 poly in z
|
542
|
-
#
|
543
|
-
# Note1:
|
544
|
-
# To compute exp(-x*x-0.5625+R/S), let s be a single
|
545
|
-
# precision number and s := x then
|
546
|
-
# -x*x = -s*s + (s-x)*(s+x)
|
547
|
-
# exp(-x*x-0.5626+R/S) =
|
548
|
-
# exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S)
|
549
|
-
# Note2:
|
550
|
-
# Here 4 and 5 make use of the asymptotic series
|
551
|
-
# exp(-x*x)
|
552
|
-
# erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) )
|
553
|
-
# x*sqrt(pi)
|
554
|
-
# We use rational approximation to approximate
|
555
|
-
# g(s)=f(1/x^2) = log(erfc(x)*x) - x*x + 0.5625
|
556
|
-
# Here is the error bound for R1/S1 and R2/S2
|
557
|
-
# |R1/S1 - f(x)| < 2**(-62.57)
|
558
|
-
# |R2/S2 - f(x)| < 2**(-61.52)
|
559
|
-
#
|
560
|
-
# 5. For inf > x >= 28
|
561
|
-
# erf(x) = sign(x) *(1 - tiny) (raise inexact)
|
562
|
-
# erfc(x) = tiny*tiny (raise underflow) if x > 0
|
563
|
-
# = 2 - tiny if x<0
|
564
|
-
#
|
565
|
-
# 7. Special case:
|
566
|
-
# erf(0) = 0, erf(inf) = 1, erf(-inf) = -1,
|
567
|
-
# erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2,
|
568
|
-
# erfc/erf(NaN) is NaN
|
569
|
-
#
|
570
|
-
# $efx8 = 1.02703333676410069053e00
|
571
|
-
#
|
572
|
-
# Coefficients for approximation to erf on [0,0.84375]
|
573
|
-
#
|
574
|
-
|
575
|
-
# Error function.
|
576
|
-
# Based on C-code for the error function developed at Sun Microsystems.
|
577
|
-
# Author:: Jaco van Kooten
|
578
|
-
|
579
|
-
def error(x)
|
580
|
-
e_efx = 1.28379167095512586316e-01
|
581
|
-
|
582
|
-
ePp = [ 1.28379167095512558561e-01,
|
583
|
-
-3.25042107247001499370e-01,
|
584
|
-
-2.84817495755985104766e-02,
|
585
|
-
-5.77027029648944159157e-03,
|
586
|
-
-2.37630166566501626084e-05 ]
|
587
|
-
|
588
|
-
eQq = [ 3.97917223959155352819e-01,
|
589
|
-
6.50222499887672944485e-02,
|
590
|
-
5.08130628187576562776e-03,
|
591
|
-
1.32494738004321644526e-04,
|
592
|
-
-3.96022827877536812320e-06 ]
|
593
|
-
|
594
|
-
# Coefficients for approximation to erf in [0.84375,1.25]
|
595
|
-
ePa = [-2.36211856075265944077e-03,
|
596
|
-
4.14856118683748331666e-01,
|
597
|
-
-3.72207876035701323847e-01,
|
598
|
-
3.18346619901161753674e-01,
|
599
|
-
-1.10894694282396677476e-01,
|
600
|
-
3.54783043256182359371e-02,
|
601
|
-
-2.16637559486879084300e-03 ]
|
602
|
-
|
603
|
-
eQa = [ 1.06420880400844228286e-01,
|
604
|
-
5.40397917702171048937e-01,
|
605
|
-
7.18286544141962662868e-02,
|
606
|
-
1.26171219808761642112e-01,
|
607
|
-
1.36370839120290507362e-02,
|
608
|
-
1.19844998467991074170e-02 ]
|
609
|
-
|
610
|
-
e_erx = 8.45062911510467529297e-01
|
611
|
-
|
612
|
-
abs_x = (if x >= 0.0 then x else -x end)
|
613
|
-
# 0 < |x| < 0.84375
|
614
|
-
if abs_x < 0.84375
|
615
|
-
#|x| < 2**-28
|
616
|
-
if abs_x < 3.7252902984619141e-9
|
617
|
-
retval = abs_x + abs_x * e_efx
|
618
|
-
else
|
619
|
-
s = x * x
|
620
|
-
p = ePp[0] + s * (ePp[1] + s * (ePp[2] + s * (ePp[3] + s * ePp[4])))
|
621
|
-
|
622
|
-
q = 1.0 + s * (eQq[0] + s * (eQq[1] + s *
|
623
|
-
( eQq[2] + s * (eQq[3] + s * eQq[4]))))
|
624
|
-
retval = abs_x + abs_x * (p / q)
|
625
|
-
end
|
626
|
-
elsif abs_x < 1.25
|
627
|
-
s = abs_x - 1.0
|
628
|
-
p = ePa[0] + s * (ePa[1] + s *
|
629
|
-
(ePa[2] + s * (ePa[3] + s *
|
630
|
-
(ePa[4] + s * (ePa[5] + s * ePa[6])))))
|
631
|
-
|
632
|
-
q = 1.0 + s * (eQa[0] + s *
|
633
|
-
(eQa[1] + s * (eQa[2] + s *
|
634
|
-
(eQa[3] + s * (eQa[4] + s * eQa[5])))))
|
635
|
-
retval = e_erx + p / q
|
636
|
-
|
637
|
-
elsif abs_x >= 6.0
|
638
|
-
retval = 1.0
|
639
|
-
else
|
640
|
-
retval = 1.0 - complementary_error(abs_x)
|
641
|
-
end
|
642
|
-
return (if x >= 0.0 then retval else -retval end)
|
643
|
-
end
|
644
|
-
|
645
|
-
# Complementary error function.
|
646
|
-
# Based on C-code for the error function developed at Sun Microsystems.
|
647
|
-
# author Jaco van Kooten
|
648
|
-
|
649
|
-
def complementary_error(x)
|
650
|
-
# Coefficients for approximation of erfc in [1.25,1/.35]
|
651
|
-
|
652
|
-
eRa = [-9.86494403484714822705e-03,
|
653
|
-
-6.93858572707181764372e-01,
|
654
|
-
-1.05586262253232909814e01,
|
655
|
-
-6.23753324503260060396e01,
|
656
|
-
-1.62396669462573470355e02,
|
657
|
-
-1.84605092906711035994e02,
|
658
|
-
-8.12874355063065934246e01,
|
659
|
-
-9.81432934416914548592e00 ]
|
660
|
-
|
661
|
-
eSa = [ 1.96512716674392571292e01,
|
662
|
-
1.37657754143519042600e02,
|
663
|
-
4.34565877475229228821e02,
|
664
|
-
6.45387271733267880336e02,
|
665
|
-
4.29008140027567833386e02,
|
666
|
-
1.08635005541779435134e02,
|
667
|
-
6.57024977031928170135e00,
|
668
|
-
-6.04244152148580987438e-02 ]
|
669
|
-
|
670
|
-
# Coefficients for approximation to erfc in [1/.35,28]
|
671
|
-
|
672
|
-
eRb = [-9.86494292470009928597e-03,
|
673
|
-
-7.99283237680523006574e-01,
|
674
|
-
-1.77579549177547519889e01,
|
675
|
-
-1.60636384855821916062e02,
|
676
|
-
-6.37566443368389627722e02,
|
677
|
-
-1.02509513161107724954e03,
|
678
|
-
-4.83519191608651397019e02 ]
|
679
|
-
|
680
|
-
eSb = [ 3.03380607434824582924e01,
|
681
|
-
3.25792512996573918826e02,
|
682
|
-
1.53672958608443695994e03,
|
683
|
-
3.19985821950859553908e03,
|
684
|
-
2.55305040643316442583e03,
|
685
|
-
4.74528541206955367215e02,
|
686
|
-
-2.24409524465858183362e01 ]
|
687
|
-
|
688
|
-
abs_x = (if x >= 0.0 then x else -x end)
|
689
|
-
if abs_x < 1.25
|
690
|
-
retval = 1.0 - error(abs_x)
|
691
|
-
elsif abs_x > 28.0
|
692
|
-
retval = 0.0
|
693
|
-
|
694
|
-
# 1.25 < |x| < 28
|
695
|
-
else
|
696
|
-
s = 1.0/(abs_x * abs_x)
|
697
|
-
if abs_x < 2.8571428
|
698
|
-
r = eRa[0] + s * (eRa[1] + s *
|
699
|
-
(eRa[2] + s * (eRa[3] + s * (eRa[4] + s *
|
700
|
-
(eRa[5] + s *(eRa[6] + s * eRa[7])
|
701
|
-
)))))
|
702
|
-
|
703
|
-
s = 1.0 + s * (eSa[0] + s * (eSa[1] + s *
|
704
|
-
(eSa[2] + s * (eSa[3] + s * (eSa[4] + s *
|
705
|
-
(eSa[5] + s * (eSa[6] + s * eSa[7])))))))
|
706
|
-
|
707
|
-
else
|
708
|
-
r = eRb[0] + s * (eRb[1] + s *
|
709
|
-
(eRb[2] + s * (eRb[3] + s * (eRb[4] + s *
|
710
|
-
(eRb[5] + s * eRb[6])))))
|
711
|
-
|
712
|
-
s = 1.0 + s * (eSb[0] + s *
|
713
|
-
(eSb[1] + s * (eSb[2] + s * (eSb[3] + s *
|
714
|
-
(eSb[4] + s * (eSb[5] + s * eSb[6]))))))
|
715
|
-
end
|
716
|
-
retval = Math.exp(-x * x - 0.5625 + r/s) / abs_x
|
717
|
-
end
|
718
|
-
return ( if x >= 0.0 then retval else 2.0 - retval end )
|
719
|
-
end
|
720
|
-
end
|
721
|
-
|