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.
@@ -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
- puts norm.rng
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
- rule '' do |t|
20
- system "cd test && ruby ts_stats.rb"
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|
@@ -1,5 +1,5 @@
1
1
  module Rubystats
2
- VERSION = '0.2.2'
2
+ VERSION = '0.2.3'
3
3
  end
4
4
 
5
5
  require 'rubystats/normal_distribution'
@@ -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
- return nil
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) + (@p - 1.0) * Math.log(x) + (@q - 1.0) * Math.log(1.0 - x)
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
@@ -36,26 +36,26 @@ module Rubystats
36
36
 
37
37
  include Rubystats::NumericalConstants
38
38
 
39
- @logGAMMACache_res = 0.0
40
- @logGAMMACache_x = 0.0
41
- @logBetaCache_res = 0.0
42
- @logBetaCache_p = 0.0
43
- @logBetaCache_q = 0.0
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 != @logBetaCache_p || q != @logBetaCache_q
47
- logBetaCache_p = p
48
- logBetaCache_q = q
49
- if p <= 0.0 || q <= 0.0 || (p + q) > LOG_GAMMA_X_MAX_VALUE
50
- logBetaCache_res = 0.0
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
- logBetaCache_res = log_gamma(p) + log_gamma(q) - log_gamma(p + q)
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
- # GAMMA function.
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 GAMMA function for a real argument X.
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 GAMMA
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 GAMMA(x)
88
- # GAMMA related constants
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
- def log_gamma(x)
206
- logGAMMACache_res = @logGAMMACache_res
207
- logGAMMACache_x = @logGAMMACache_x
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 logGAMMA_xBig
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 == logGAMMACache_x
259
- return logGAMMACache_res
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 * xm1 * (lg_d1 + xm1 * (xnum / xden))
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
- logGAMMACache_x = x
335
- logGAMMACache_res = res
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 GAMMA function.
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 incomplete_GAMMA(a, x)
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 GAMMA_series_expansion(a, x)
373
+ return gamma_series_expansion(a, x)
353
374
  else
354
- return 1.0-GAMMA_fraction(a, x)
375
+ return 1.0-gamma_fraction(a, x)
355
376
  end
356
377
  end
357
378
 
358
379
  # Author:: Jaco van Kooten
359
- def GAMMA_series_expansion(a, x)
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 GAMMA_fraction(a, x)
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
- pdf = 0.0
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
- pdf = pdf(x)
155
- if pdf != 0.0
156
- dx = error / pdf
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 || pdf == 0.0
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
@@ -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.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-05-09 00:00:00 -07:00
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.5.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.1.1
84
+ rubygems_version: 1.2.0
84
85
  signing_key:
85
86
  specification_version: 2
86
87
  summary: Port of PHPMath to Ruby