rubystats 0.2.2 → 0.2.3
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 +4 -0
- data/README.txt +9 -9
- data/Rakefile +8 -2
- data/lib/rubystats.rb +1 -1
- data/lib/rubystats/beta_distribution.rb +4 -3
- data/lib/rubystats/modules.rb +60 -40
- data/lib/rubystats/probability_distribution.rb +5 -5
- data/test/tc_beta.rb +18 -1
- metadata +5 -4
data/History.txt
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
=== 0.2.3 / 2008-07-06
|
2
|
+
* Fixing bug #21100 - problem with Beta distribution calculations when p and q values are small.
|
3
|
+
* Minor code cleanup for readability in a few places.
|
4
|
+
|
1
5
|
=== 0.2.2 / 2008-05-09
|
2
6
|
* Added exponential distribution class
|
3
7
|
* Replaced constants in NumericalConstants module with uppercase versions to follow Ruby convention
|
data/README.txt
CHANGED
@@ -49,11 +49,11 @@ Also includes Fisher's Exact Test
|
|
49
49
|
== SYNOPSIS:
|
50
50
|
=== Example: normal distribution with mean of 10 and standard deviation of 2
|
51
51
|
|
52
|
-
norm = Rubystats::NormalDistribution.new(10, 2)
|
53
|
-
cdf = norm.cdf(11)
|
54
|
-
pdf = norm.pdf(11)
|
55
|
-
puts "CDF(11): #{cdf}"
|
56
|
-
puts "PDF(11): #{pdf}"
|
52
|
+
norm = Rubystats::NormalDistribution.new(10, 2)
|
53
|
+
cdf = norm.cdf(11)
|
54
|
+
pdf = norm.pdf(11)
|
55
|
+
puts "CDF(11): #{cdf}"
|
56
|
+
puts "PDF(11): #{pdf}"
|
57
57
|
|
58
58
|
Output:
|
59
59
|
CDF(11): 0.691462461274013
|
@@ -61,10 +61,10 @@ Output:
|
|
61
61
|
|
62
62
|
=== Example: get some random numbers from a normal distribution
|
63
63
|
|
64
|
-
puts "Random numbers from normal distribution:"
|
65
|
-
10.times do
|
66
|
-
|
67
|
-
end
|
64
|
+
puts "Random numbers from normal distribution:"
|
65
|
+
10.times do
|
66
|
+
puts norm.rng
|
67
|
+
end
|
68
68
|
|
69
69
|
(sample) Output:
|
70
70
|
|
data/Rakefile
CHANGED
@@ -4,6 +4,7 @@ require 'rubygems'
|
|
4
4
|
require 'hoe'
|
5
5
|
$:.unshift(File.dirname(__FILE__) + "/lib")
|
6
6
|
require 'rubystats'
|
7
|
+
#require './lib/rubystats.rb'
|
7
8
|
|
8
9
|
Hoe.new('rubystats', Rubystats::VERSION) do |p|
|
9
10
|
p.name = "rubystats"
|
@@ -16,10 +17,15 @@ Hoe.new('rubystats', Rubystats::VERSION) do |p|
|
|
16
17
|
p.remote_rdoc_dir = '' # Release to root
|
17
18
|
end
|
18
19
|
|
19
|
-
|
20
|
-
|
20
|
+
desc "Run all tests"
|
21
|
+
task :test do
|
22
|
+
Rake::TestTask.new("test") do |t|
|
23
|
+
t.test_files = FileList['test/tc*.rb']
|
24
|
+
t.verbose = false
|
25
|
+
end
|
21
26
|
end
|
22
27
|
|
28
|
+
#Use Allison template if available
|
23
29
|
ALLISON = "/opt/local/lib/ruby/gems/1.8/gems/allison-2.0.3/lib/allison.rb"
|
24
30
|
|
25
31
|
Rake::RDocTask.new do |rd|
|
data/lib/rubystats.rb
CHANGED
@@ -10,7 +10,7 @@ module Rubystats
|
|
10
10
|
#dgr_q = degrees of freedom q
|
11
11
|
def initialize(dgr_p, dgr_q)
|
12
12
|
if dgr_p <= 0 || dgr_q <= 0
|
13
|
-
|
13
|
+
raise ArgumentError.new("Paramters must be greater than zero.")
|
14
14
|
end
|
15
15
|
@p = dgr_p.to_f
|
16
16
|
@q = dgr_q.to_f
|
@@ -41,8 +41,9 @@ module Rubystats
|
|
41
41
|
if (x == 0.0) || (x == 1.0)
|
42
42
|
return 0.0
|
43
43
|
else
|
44
|
-
return Math.exp( - log_beta(@p, @q) +
|
45
|
-
)
|
44
|
+
return Math.exp( -1.0 * log_beta(@p, @q) +
|
45
|
+
(@p - 1.0) * Math.log(x) +
|
46
|
+
(@q - 1.0) * Math.log(1.0 - x))
|
46
47
|
end
|
47
48
|
end
|
48
49
|
end
|
data/lib/rubystats/modules.rb
CHANGED
@@ -36,26 +36,26 @@ module Rubystats
|
|
36
36
|
|
37
37
|
include Rubystats::NumericalConstants
|
38
38
|
|
39
|
-
@
|
40
|
-
@
|
41
|
-
@
|
42
|
-
@
|
43
|
-
@
|
39
|
+
@log_gamma_cache_res = 0.0
|
40
|
+
@log_gamma_cache_x = 0.0
|
41
|
+
@log_beta_cache_res = 0.0
|
42
|
+
@log_beta_cache_p = 0.0
|
43
|
+
@log_beta_cache_q = 0.0
|
44
44
|
|
45
45
|
def log_beta(p,q)
|
46
|
-
if p != @
|
47
|
-
|
48
|
-
|
49
|
-
if p <= 0.0 || q <= 0.0 || (p + q) > LOG_GAMMA_X_MAX_VALUE
|
50
|
-
|
46
|
+
if p != @log_beta_cache_p || q != @log_beta_cache_q
|
47
|
+
@log_beta_cache_p = p
|
48
|
+
@log_beta_cache_q = q
|
49
|
+
if (p <= 0.0) || (q <= 0.0) || (p + q) > LOG_GAMMA_X_MAX_VALUE
|
50
|
+
@log_beta_cache_res = 0.0
|
51
51
|
else
|
52
|
-
|
52
|
+
@log_beta_cache_res = log_gamma(p) + log_gamma(q) - log_gamma(p + q)
|
53
53
|
end
|
54
|
-
return logBetaCache_res
|
55
54
|
end
|
55
|
+
return @log_beta_cache_res
|
56
56
|
end
|
57
57
|
|
58
|
-
#
|
58
|
+
# Gamma function.
|
59
59
|
# Based on public domain NETLIB (Fortran) code by W. J. Cody and L. Stoltz<BR>
|
60
60
|
# Applied Mathematics Division<BR>
|
61
61
|
# Argonne National Laboratory<BR>
|
@@ -68,9 +68,9 @@ module Rubystats
|
|
68
68
|
# </OL></P><P>
|
69
69
|
# From the original documentation:
|
70
70
|
# </P><P>
|
71
|
-
# This routine calculates the
|
71
|
+
# This routine calculates the Gamma function for a real argument X.
|
72
72
|
# Computation is based on an algorithm outlined in reference 1.
|
73
|
-
# The program uses rational functions that approximate the
|
73
|
+
# The program uses rational functions that approximate the Gamma
|
74
74
|
# function to at least 20 significant decimal digits. Coefficients
|
75
75
|
# for the approximation over the interval (1,2) are unpublished.
|
76
76
|
# Those for the approximation for X .GE. 12 are from reference 2.
|
@@ -84,8 +84,8 @@ module Rubystats
|
|
84
84
|
# </P>
|
85
85
|
# Author:: Jaco van Kooten
|
86
86
|
|
87
|
-
def
|
88
|
-
#
|
87
|
+
def orig_gamma(x)
|
88
|
+
# Gamma related constants
|
89
89
|
g_p = [ -1.71618513886549492533811, 24.7656508055759199108314,
|
90
90
|
-379.804256470945635097577, 629.331155312818442661052,
|
91
91
|
866.966202790413211295064, -31451.2729688483675254357,
|
@@ -97,11 +97,11 @@ module Rubystats
|
|
97
97
|
g_c = [-0.001910444077728, 8.4171387781295e-4, -5.952379913043012e-4,
|
98
98
|
7.93650793500350248e-4, -0.002777777777777681622553,
|
99
99
|
0.08333333333333333331554247, 0.0057083835261 ]
|
100
|
-
fact=1.0
|
101
|
-
i=0
|
102
|
-
n=0
|
103
|
-
y=x
|
104
|
-
parity=false
|
100
|
+
fact = 1.0
|
101
|
+
i = 0
|
102
|
+
n = 0
|
103
|
+
y = x
|
104
|
+
parity = false
|
105
105
|
if y <= 0.0
|
106
106
|
# ----------------------------------------------------------------------
|
107
107
|
# Argument is negative
|
@@ -202,10 +202,31 @@ module Rubystats
|
|
202
202
|
end
|
203
203
|
end
|
204
204
|
|
205
|
-
|
206
|
-
|
207
|
-
|
205
|
+
#TODO test this
|
206
|
+
def gamma(_x)
|
207
|
+
return 0 if _x == 0.0
|
208
|
+
|
209
|
+
p0 = 1.000000000190015
|
210
|
+
p = {1 => 76.18009172947146,
|
211
|
+
2 => -86.50532032941677,
|
212
|
+
3 => 24.01409824083091,
|
213
|
+
4 => -1.231739572450155,
|
214
|
+
5 => 1.208650973866179e-3,
|
215
|
+
6 => -5.395239384953e-6}
|
216
|
+
|
217
|
+
y = x = _x
|
218
|
+
tmp = x + 5.5
|
219
|
+
tmp -= (x + 0.5) * Math.log(tmp)
|
220
|
+
|
221
|
+
summer = p0
|
222
|
+
for j in (1 ... 6)
|
223
|
+
y += 1
|
224
|
+
summer += (p[j] / y)
|
225
|
+
end
|
226
|
+
return Math.exp(0 - tmp + Math.log(2.5066282746310005 * summer / x))
|
227
|
+
end
|
208
228
|
|
229
|
+
def log_gamma(x)
|
209
230
|
lg_d1 = -0.5772156649015328605195174
|
210
231
|
lg_d2 = 0.4227843350984671393993777
|
211
232
|
lg_d4 = 1.791759469228055000094023
|
@@ -251,12 +272,12 @@ module Rubystats
|
|
251
272
|
-0.002777777777777681622553, 0.08333333333333333331554247,
|
252
273
|
0.0057083835261 ]
|
253
274
|
|
254
|
-
# Rough estimate of the fourth root of
|
275
|
+
# Rough estimate of the fourth root of logGamma_xBig
|
255
276
|
lg_frtbig = 2.25e76
|
256
277
|
pnt68 = 0.6796875
|
257
278
|
|
258
|
-
if x ==
|
259
|
-
return
|
279
|
+
if x == @log_gamma_cache_x
|
280
|
+
return @log_gamma_cache_res
|
260
281
|
end
|
261
282
|
|
262
283
|
y = x
|
@@ -280,7 +301,7 @@ module Rubystats
|
|
280
301
|
xnum = xnum * xm1 + lg_p1[i]
|
281
302
|
xden = xden * xm1 + lg_q1[i]
|
282
303
|
end
|
283
|
-
res = corr
|
304
|
+
res = corr + xm1 * (lg_d1 + xm1 * (xnum / xden))
|
284
305
|
else
|
285
306
|
xm2 = y - 1.0
|
286
307
|
xden = 1.0
|
@@ -331,13 +352,13 @@ module Rubystats
|
|
331
352
|
res = MAX_VALUE
|
332
353
|
end
|
333
354
|
# final adjustments and return
|
334
|
-
|
335
|
-
|
355
|
+
@log_gamma_cache_x = x
|
356
|
+
@log_gamma_cache_res = res
|
336
357
|
return res
|
337
358
|
end
|
338
359
|
|
339
360
|
|
340
|
-
# Incomplete
|
361
|
+
# Incomplete Gamma function.
|
341
362
|
# The computation is based on approximations presented in
|
342
363
|
# Numerical Recipes, Chapter 6.2 (W.H. Press et al, 1992).
|
343
364
|
# @param a require a>=0
|
@@ -345,18 +366,18 @@ module Rubystats
|
|
345
366
|
# @return 0 if x<0, a<=0 or a>2.55E305 to avoid errors and over/underflow
|
346
367
|
# @author Jaco van Kooten
|
347
368
|
|
348
|
-
def
|
369
|
+
def incomplete_gamma(a, x)
|
349
370
|
if x <= 0.0 || a <= 0.0 || a > LOG_GAMMA_X_MAX_VALUE
|
350
371
|
return 0.0
|
351
372
|
elsif x < (a + 1.0)
|
352
|
-
return
|
373
|
+
return gamma_series_expansion(a, x)
|
353
374
|
else
|
354
|
-
return 1.0-
|
375
|
+
return 1.0-gamma_fraction(a, x)
|
355
376
|
end
|
356
377
|
end
|
357
378
|
|
358
379
|
# Author:: Jaco van Kooten
|
359
|
-
def
|
380
|
+
def gamma_series_expansion(a, x)
|
360
381
|
ap = a
|
361
382
|
del = 1.0 / a
|
362
383
|
sum = del
|
@@ -372,7 +393,7 @@ module Rubystats
|
|
372
393
|
end
|
373
394
|
|
374
395
|
# Author:: Jaco van Kooten
|
375
|
-
def
|
396
|
+
def gamma_fraction(a, x)
|
376
397
|
b = x + 1.0 - a
|
377
398
|
c = 1.0 / XMININ
|
378
399
|
d = 1.0 / b
|
@@ -424,14 +445,13 @@ module Rubystats
|
|
424
445
|
return 0.0
|
425
446
|
elsif x >= 1.0
|
426
447
|
return 1.0
|
427
|
-
elsif p <= 0.0 || q <= 0.0 || (p + q) > LOG_GAMMA_X_MAX_VALUE
|
448
|
+
elsif (p <= 0.0) || (q <= 0.0) || (p + q) > LOG_GAMMA_X_MAX_VALUE
|
428
449
|
return 0.0
|
429
450
|
else
|
430
451
|
beta_gam = Math.exp( -log_beta(p, q) + p * Math.log(x) + q * Math.log(1.0 - x) )
|
431
452
|
if x < (p + 1.0) / (p + q + 2.0)
|
432
453
|
return beta_gam * beta_fraction(x, p, q) / p
|
433
454
|
else
|
434
|
-
beta_frac = beta_fraction(1.0 - x, p, q)
|
435
455
|
return 1.0 - (beta_gam * beta_fraction(1.0 - x, q, p) / q)
|
436
456
|
end
|
437
457
|
end
|
@@ -469,7 +489,7 @@ module Rubystats
|
|
469
489
|
if c.abs < XMININ
|
470
490
|
c = XMININ
|
471
491
|
end
|
472
|
-
frac *= h * c
|
492
|
+
frac *= (h * c)
|
473
493
|
# odd index for d
|
474
494
|
d = -(p + m) * (sum_pq + m) * x / ((p + m2) * (p_plus + m2))
|
475
495
|
h = 1.0 + d * h
|
@@ -140,7 +140,7 @@ module Rubystats
|
|
140
140
|
x = guess
|
141
141
|
x_new = guess
|
142
142
|
error = 0.0
|
143
|
-
|
143
|
+
_pdf = 0.0
|
144
144
|
dx = 1000.0
|
145
145
|
i = 0
|
146
146
|
while ( dx.abs > accuracy && (i += 1) < max_iteration )
|
@@ -151,15 +151,15 @@ module Rubystats
|
|
151
151
|
else
|
152
152
|
x_hi = x
|
153
153
|
end
|
154
|
-
|
155
|
-
if
|
156
|
-
dx = error /
|
154
|
+
_pdf = pdf(x)
|
155
|
+
if _pdf != 0.0
|
156
|
+
dx = error / _pdf
|
157
157
|
x_new = x -dx
|
158
158
|
end
|
159
159
|
# If the NR fails to converge (which for example may be the
|
160
160
|
# case if the initial guess is too rough) we apply a bisection
|
161
161
|
# step to determine a more narrow interval around the root.
|
162
|
-
if x_new < x_lo || x_new > x_hi ||
|
162
|
+
if x_new < x_lo || x_new > x_hi || _pdf == 0.0
|
163
163
|
x_new = (x_lo + x_hi) / 2.0
|
164
164
|
dx = x_new - x
|
165
165
|
end
|
data/test/tc_beta.rb
CHANGED
@@ -40,9 +40,26 @@ class TestBeta < Test::Unit::TestCase
|
|
40
40
|
inv_cdf = beta.icdf(cdf)
|
41
41
|
assert_in_delta(x, inv_cdf, 0.00000001)
|
42
42
|
end
|
43
|
-
|
44
43
|
end
|
45
44
|
|
45
|
+
def test_low_p_and_q_values
|
46
|
+
p = 1.5
|
47
|
+
q = 1.0
|
48
|
+
beta = Rubystats::BetaDistribution.new(p,q)
|
49
|
+
|
50
|
+
#from PHPExcel/PHPMath output
|
51
|
+
expected_icdf_vals = [
|
52
|
+
0.096548938, 0.153261886, 0.200829885, 0.243288080, 0.282310809, 0.318797571, 0.353302082, 0.386195754, 0.417742995, 0.448140475, 0.477539492, 0.506059599, 0.533797339, 0.560832096, 0.587230146, 0.613047546, 0.638332246, 0.663125670, 0.687463910, 0.711378661, 0.734897945, 0.758046692, 0.780847206, 0.803319540, 0.825481812, 0.847350458, 0.868940446, 0.890265460, 0.911338047, 0.932169752, 0.952771225, 0.973152319, 0.993322173]
|
53
|
+
expected_cdf_vals = [
|
54
|
+
0.005196152, 0.014696938, 0.027000000, 0.041569219, 0.058094750, 0.076367532, 0.096234090, 0.117575508, 0.140296115, 0.164316767, 0.189570567, 0.216000000, 0.243554922, 0.272191109, 0.301869177, 0.332553755, 0.364212850, 0.396817338, 0.430340563, 0.464758002, 0.500046998, 0.536186535, 0.573157047, 0.610940259, 0.649519053, 0.688877348, 0.729000000, 0.769872717, 0.811481978, 0.853814968, 0.896859521, 0.940604061, 0.985037563 ]
|
55
|
+
i = 0
|
56
|
+
0.03.step(1.0, 0.03) do |x|
|
57
|
+
assert_in_delta expected_icdf_vals[i], beta.icdf(x), 0.00000001
|
58
|
+
assert_in_delta expected_cdf_vals[i], beta.cdf(x), 0.00000001
|
59
|
+
i += 1
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
46
63
|
def test_control_limits
|
47
64
|
trials = 50
|
48
65
|
alpha = 0.05
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubystats
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bryan Donovan - http://www.bryandonovan.com
|
@@ -9,17 +9,18 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-07-06 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: hoe
|
17
|
+
type: :development
|
17
18
|
version_requirement:
|
18
19
|
version_requirements: !ruby/object:Gem::Requirement
|
19
20
|
requirements:
|
20
21
|
- - ">="
|
21
22
|
- !ruby/object:Gem::Version
|
22
|
-
version: 1.
|
23
|
+
version: 1.7.0
|
23
24
|
version:
|
24
25
|
description: Ruby Stats is a port of the statistics libraries from PHPMath. Probability distributions include binomial, beta, and normal distributions with PDF, CDF and inverse CDF as well as Fisher's Exact Test.
|
25
26
|
email: b.dondo+rubyforge@gmail.com
|
@@ -80,7 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
81
|
requirements: []
|
81
82
|
|
82
83
|
rubyforge_project: rubystats
|
83
|
-
rubygems_version: 1.
|
84
|
+
rubygems_version: 1.2.0
|
84
85
|
signing_key:
|
85
86
|
specification_version: 2
|
86
87
|
summary: Port of PHPMath to Ruby
|