rubystats 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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/normal_distribution.rb
DELETED
@@ -1,114 +0,0 @@
|
|
1
|
-
require 'probability_distribution'
|
2
|
-
require 'modules/special_math'
|
3
|
-
# This class provides an object for encapsulating normal distributions
|
4
|
-
# Ported to Ruby from PHPMath class by Bryan Donovan
|
5
|
-
# Author:: Jaco van Kooten
|
6
|
-
# Author:: Paul Meagher
|
7
|
-
# Author:: Bryan Donovan (mailto:bryandonovan@myrealbox.com)
|
8
|
-
|
9
|
-
class NormalDistribution < ProbabilityDistribution
|
10
|
-
include SpecialMath
|
11
|
-
|
12
|
-
# Constructs a normal distribution (defaults to zero mean and
|
13
|
-
# unity variance).
|
14
|
-
def initialize(mu=0.0, sigma=1.0)
|
15
|
-
@mean = mu
|
16
|
-
if sigma <= 0.0
|
17
|
-
return "error"
|
18
|
-
end
|
19
|
-
@stdev = sigma
|
20
|
-
@variance = sigma**2
|
21
|
-
@pdf_denominator = Sqrt2pi * Math.sqrt(@variance)
|
22
|
-
@cdf_denominator = Sqrt2 * Math.sqrt(@variance)
|
23
|
-
end
|
24
|
-
|
25
|
-
# Returns the mean of the distribution
|
26
|
-
def get_mean
|
27
|
-
return @mean
|
28
|
-
end
|
29
|
-
|
30
|
-
# Returns the standard deviation of the distribution
|
31
|
-
def get_standard_deviation
|
32
|
-
return @stdev
|
33
|
-
end
|
34
|
-
|
35
|
-
# Returns the variance of the distribution
|
36
|
-
def get_variance
|
37
|
-
return @variance
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
# Obtain single PDF value
|
43
|
-
# Returns the probability that a stochastic variable x has the value X,
|
44
|
-
# i.e. P(x=X)
|
45
|
-
def get_pdf(x)
|
46
|
-
Math.exp( -((x-@mean)**2) / (2 * @variance)) / @pdf_denominator
|
47
|
-
end
|
48
|
-
|
49
|
-
# Obtain single CDF value
|
50
|
-
# Returns the probability that a stochastic variable x is less than X,
|
51
|
-
# i.e. P(x<X)
|
52
|
-
def get_cdf(x)
|
53
|
-
complementary_error( -(x - @mean) / @cdf_denominator) / 2
|
54
|
-
end
|
55
|
-
|
56
|
-
# Obtain single inverse CDF value.
|
57
|
-
# returns the value X for which P(x<X).
|
58
|
-
def get_icdf(p)
|
59
|
-
check_range(p)
|
60
|
-
if p == 0.0
|
61
|
-
return -Max_value
|
62
|
-
end
|
63
|
-
if p == 1.0
|
64
|
-
return Max_value
|
65
|
-
end
|
66
|
-
if p == 0.5
|
67
|
-
return @mean
|
68
|
-
end
|
69
|
-
|
70
|
-
mean_save = @mean
|
71
|
-
var_save = @variance
|
72
|
-
pdf_D_save = @pdf_denominator
|
73
|
-
cdf_D_save = @cdf_denominator
|
74
|
-
@mean = 0.0
|
75
|
-
@variance = 1.0
|
76
|
-
@pdf_denominator = Math.sqrt(Two_pi)
|
77
|
-
@cdf_denominator = Sqrt2
|
78
|
-
x = find_root(p, 0.0, -100.0, 100.0)
|
79
|
-
#scale back
|
80
|
-
@mean = mean_save
|
81
|
-
@variance = var_save
|
82
|
-
@pdf_denominator = pdf_D_save
|
83
|
-
@cdf_denominator = cdf_D_save
|
84
|
-
return x * Math.sqrt(@variance) + @mean
|
85
|
-
end
|
86
|
-
|
87
|
-
# Uses the polar form of the Box-Muller transformation which
|
88
|
-
# is both faster and more robust numerically than basic Box-Muller
|
89
|
-
# transform. To speed up repeated RNG computations, two random values
|
90
|
-
# are computed after the while loop and the second one is saved and
|
91
|
-
# directly used if the method is called again.
|
92
|
-
# see http://www.taygeta.com/random/gaussian.html
|
93
|
-
# returns single normal deviate
|
94
|
-
def get_rng
|
95
|
-
if @use_last
|
96
|
-
y1 = @last
|
97
|
-
@use_last = false
|
98
|
-
else
|
99
|
-
until w < 1.0 do
|
100
|
-
r1 = Kernel.rand
|
101
|
-
r2 = Kernel.rand
|
102
|
-
x1 = 2.0 * r1 - 1.0
|
103
|
-
x2 = 2.0 * r2 - 1.0
|
104
|
-
w = x1 * x1 * x2 * x2
|
105
|
-
end
|
106
|
-
w = Math.sqrt((-2.0 * Math.log(w)) / w)
|
107
|
-
y1 = x1 * w
|
108
|
-
@last = x2 * w
|
109
|
-
@use_last = true
|
110
|
-
end
|
111
|
-
return @mean + y1 * Math.sqrt(@variance)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
@@ -1,132 +0,0 @@
|
|
1
|
-
require 'modules/numerical_constants'
|
2
|
-
require 'modules/extra_math'
|
3
|
-
require 'modules/special_math'
|
4
|
-
|
5
|
-
class ProbabilityDistribution
|
6
|
-
include NumericalConstants
|
7
|
-
include SpecialMath
|
8
|
-
include ExtraMath
|
9
|
-
|
10
|
-
def initialize
|
11
|
-
end
|
12
|
-
|
13
|
-
def mean
|
14
|
-
get_mean
|
15
|
-
end
|
16
|
-
|
17
|
-
def get_mean
|
18
|
-
end
|
19
|
-
|
20
|
-
|
21
|
-
def pdf(x)
|
22
|
-
if x.class == Array
|
23
|
-
pdf_vals = []
|
24
|
-
for i in (0..x.length)
|
25
|
-
pdf_vals[i] = get_pdf(x[i])
|
26
|
-
end
|
27
|
-
return pdf_vals
|
28
|
-
else
|
29
|
-
return get_pdf(x)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def get_pdf(x)
|
34
|
-
end
|
35
|
-
|
36
|
-
def cdf(x)
|
37
|
-
if x.class == Array
|
38
|
-
cdf_vals = []
|
39
|
-
for i in (0...x.size)
|
40
|
-
cdf_vals[i] = get_cdf(x[i])
|
41
|
-
end
|
42
|
-
return cdf_vals
|
43
|
-
else
|
44
|
-
return get_cdf(x)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def get_cdf(x)
|
49
|
-
end
|
50
|
-
|
51
|
-
def icdf(p)
|
52
|
-
if p.class == Array
|
53
|
-
inv_vals = []
|
54
|
-
for i in (0..p.length)
|
55
|
-
inv_vals[i] = get_icdf(p[i])
|
56
|
-
end
|
57
|
-
return inv_vals
|
58
|
-
else
|
59
|
-
return get_icdf(p)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def get_icdf(p)
|
64
|
-
end
|
65
|
-
|
66
|
-
def rng(n=1)
|
67
|
-
if n < 1
|
68
|
-
return "Number of random numbers to return must be 1 or greater"
|
69
|
-
end
|
70
|
-
if (n > 1)
|
71
|
-
rnd_vals = []
|
72
|
-
for i in (0..n)
|
73
|
-
rnd_vals[i] = get_rng()
|
74
|
-
end
|
75
|
-
return rnd_vals
|
76
|
-
else
|
77
|
-
return get_rng()
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def get_rng()
|
82
|
-
end
|
83
|
-
|
84
|
-
def check_range(x, lo=0.0, hi=1.0)
|
85
|
-
if (x < lo) || (x > hi)
|
86
|
-
return "error"
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def get_factorial(n)
|
91
|
-
if n <= 1
|
92
|
-
return 1
|
93
|
-
else
|
94
|
-
return n * get_factorial(n-1)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
def find_root (prob, guess, x_lo, x_hi)
|
99
|
-
accuracy = 1.0e-10
|
100
|
-
max_iteration = 150
|
101
|
-
x = guess
|
102
|
-
x_new = guess
|
103
|
-
error = 0.0
|
104
|
-
pdf = 0.0
|
105
|
-
dx = 1000.0
|
106
|
-
i = 0
|
107
|
-
while ( dx.abs > accuracy && (i += 1) < max_iteration )
|
108
|
-
#Apply Newton-Raphson step
|
109
|
-
error = cdf(x) - prob
|
110
|
-
if error < 0.0
|
111
|
-
x_lo = x
|
112
|
-
else
|
113
|
-
x_hi = x
|
114
|
-
end
|
115
|
-
pdf = pdf(x)
|
116
|
-
if pdf != 0.0
|
117
|
-
dx = error / pdf
|
118
|
-
x_new = x -dx
|
119
|
-
end
|
120
|
-
# If the NR fails to converge (which for example may be the
|
121
|
-
# case if the initial guess is to rough) we apply a bisection
|
122
|
-
# step to determine a more narrow interval around the root.
|
123
|
-
if x_new < x_lo || x_new > x_hi || pdf == 0.0
|
124
|
-
x_new = (x_lo + x_hi) / 2.0
|
125
|
-
dx = x_new - x
|
126
|
-
end
|
127
|
-
x = x_new
|
128
|
-
end
|
129
|
-
return x
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
data/tests/tc_norm.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
2
|
-
require 'test/unit'
|
3
|
-
require 'normal_distribution'
|
4
|
-
|
5
|
-
class TestNormal < Test::Unit::TestCase
|
6
|
-
def test_simple
|
7
|
-
|
8
|
-
norm = NormalDistribution.new(10,2)
|
9
|
-
cdf = norm.cdf(11)
|
10
|
-
|
11
|
-
assert_equal("0.691462461274013",cdf.to_s)
|
12
|
-
end
|
13
|
-
end
|