rubystats 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|