distribution 0.7.2 → 0.7.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +3 -1
- data/History.txt +3 -0
- data/lib/distribution.rb +1 -4
- data/lib/distribution/beta.rb +6 -8
- data/lib/distribution/beta/gsl.rb +6 -6
- data/lib/distribution/beta/java.rb +1 -1
- data/lib/distribution/beta/ruby.rb +16 -18
- data/lib/distribution/binomial.rb +10 -11
- data/lib/distribution/binomial/gsl.rb +6 -5
- data/lib/distribution/binomial/java.rb +1 -1
- data/lib/distribution/binomial/ruby.rb +19 -17
- data/lib/distribution/chisquare/ruby.rb +44 -39
- data/lib/distribution/f.rb +10 -11
- data/lib/distribution/f/ruby.rb +107 -105
- data/lib/distribution/version.rb +1 -1
- data/spec/chisquare_spec.rb +1 -0
- data/spec/f_spec.rb +73 -71
- data/spec/spec_helper.rb +2 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4904710a92ef44ae987119ac6c214ea860735cd9
|
4
|
+
data.tar.gz: 8a6381d47062634afade73cafbcd093603db985b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9142471e941e7a2a44ecc727c698fc18bf46da46964e0f49ea2e80ebd829284a1b53284ceaed4135d7ac9ade786e04a4bc155d9e3bb104151925f1d88b6ec9f8
|
7
|
+
data.tar.gz: 2f019d5d7388e7af9c0d7d4e93f02eacdd06ac302bc5d7f72172e8fa6df00fc5c23fbe99a035f87989ad2cb692da523eaa1127338e3f673da84b3e006a0a69b3
|
data/Gemfile
CHANGED
data/History.txt
CHANGED
data/lib/distribution.rb
CHANGED
@@ -39,7 +39,6 @@ require 'distribution/version'
|
|
39
39
|
# Distribution::Normal.p_value(0.95)
|
40
40
|
# => 1.64485364660836
|
41
41
|
module Distribution
|
42
|
-
|
43
42
|
SQ2PI = Math.sqrt(2 * Math::PI)
|
44
43
|
|
45
44
|
module Shorthand
|
@@ -150,7 +149,5 @@ module Distribution
|
|
150
149
|
require 'distribution/lognormal'
|
151
150
|
require 'distribution/weibull'
|
152
151
|
|
153
|
-
if has_java?
|
154
|
-
init_java
|
155
|
-
end
|
152
|
+
init_java if has_java?
|
156
153
|
end
|
data/lib/distribution/beta.rb
CHANGED
@@ -5,22 +5,21 @@ require 'distribution/beta/java'
|
|
5
5
|
|
6
6
|
module Distribution
|
7
7
|
# From Wikipedia:
|
8
|
-
# In probability theory and statistics, the beta distribution
|
9
|
-
# is a family of continuous probability distributions defined
|
10
|
-
# on the interval (0, 1) parameterized by two positive shape
|
11
|
-
# parameters, typically denoted by alpha and beta.
|
8
|
+
# In probability theory and statistics, the beta distribution
|
9
|
+
# is a family of continuous probability distributions defined
|
10
|
+
# on the interval (0, 1) parameterized by two positive shape
|
11
|
+
# parameters, typically denoted by alpha and beta.
|
12
12
|
# This module calculate cdf and inverse cdf for Beta Distribution.
|
13
13
|
#
|
14
14
|
module Beta
|
15
15
|
extend Distributable
|
16
|
-
SHORTHAND='beta'
|
16
|
+
SHORTHAND = 'beta'
|
17
17
|
create_distribution_methods
|
18
18
|
|
19
19
|
##
|
20
20
|
# :singleton-method: pdf(x,a,b)
|
21
21
|
# Returns PDF of of Beta distribution with parameters a and b
|
22
22
|
|
23
|
-
|
24
23
|
##
|
25
24
|
# :singleton-method: cdf(x,a,b)
|
26
25
|
# Returns the integral of Beta distribution with parameters a and b
|
@@ -28,7 +27,6 @@ module Distribution
|
|
28
27
|
##
|
29
28
|
# :singleton-method: p_value(qn,a,b)
|
30
29
|
# Return the quantile of the corresponding integral +qn+
|
31
|
-
# on a beta distribution's cdf with parameters a and b
|
32
|
-
|
30
|
+
# on a beta distribution's cdf with parameters a and b
|
33
31
|
end
|
34
32
|
end
|
@@ -2,21 +2,21 @@ module Distribution
|
|
2
2
|
module Beta
|
3
3
|
module GSL_
|
4
4
|
class << self
|
5
|
-
def pdf(x,a,b)
|
6
|
-
GSL::Ran
|
5
|
+
def pdf(x, a, b)
|
6
|
+
GSL::Ran.beta_pdf(x.to_f, a.to_f, b.to_f)
|
7
7
|
end
|
8
8
|
# Return the P-value of the corresponding integral with
|
9
9
|
# k degrees of freedom
|
10
|
-
def p_value(pr,a,b)
|
11
|
-
GSL::Cdf
|
10
|
+
def p_value(pr, a, b)
|
11
|
+
GSL::Cdf.beta_Pinv(pr.to_f, a.to_f, b.to_f)
|
12
12
|
end
|
13
13
|
# Beta cumulative distribution function (cdf).
|
14
14
|
#
|
15
15
|
# Returns the integral of Beta distribution
|
16
16
|
# with parameters +a+ and +b+ over [0, x]
|
17
17
|
#
|
18
|
-
def cdf(x,a,b)
|
19
|
-
GSL::Cdf
|
18
|
+
def cdf(x, a, b)
|
19
|
+
GSL::Cdf.beta_P(x.to_f, a.to_f, b.to_f)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -3,7 +3,6 @@ module Distribution
|
|
3
3
|
module Beta
|
4
4
|
module Ruby_
|
5
5
|
class << self
|
6
|
-
|
7
6
|
include Math
|
8
7
|
# Beta distribution probability density function
|
9
8
|
#
|
@@ -13,38 +12,38 @@ module Distribution
|
|
13
12
|
#
|
14
13
|
# == References
|
15
14
|
# * http://www.gnu.org/s/gsl/manual/html_node/The-Gamma-Distribution.html
|
16
|
-
def pdf(x,a,b)
|
15
|
+
def pdf(x, a, b)
|
17
16
|
return 0 if x < 0 || x > 1
|
18
17
|
|
19
|
-
gab = Math.lgamma(a+b).first
|
18
|
+
gab = Math.lgamma(a + b).first
|
20
19
|
ga = Math.lgamma(a).first
|
21
20
|
gb = Math.lgamma(b).first
|
22
21
|
|
23
22
|
if x == 0.0 || x == 1.0
|
24
|
-
Math.exp(gab - ga - gb) * x**(a-1) * (1-x)**(b-1)
|
23
|
+
Math.exp(gab - ga - gb) * x**(a - 1) * (1 - x)**(b - 1)
|
25
24
|
else
|
26
|
-
Math.exp(gab - ga - gb + Math.log(x)*(a-1) + Math::Log.log1p(-x)*(b-1))
|
25
|
+
Math.exp(gab - ga - gb + Math.log(x) * (a - 1) + Math::Log.log1p(-x) * (b - 1))
|
27
26
|
end
|
28
27
|
end
|
29
28
|
|
30
29
|
# Gamma cumulative distribution function
|
31
30
|
# Translated from GSL-1.9: cdf/beta.c gsl_cdf_beta_P
|
32
|
-
def cdf(x,a,b)
|
31
|
+
def cdf(x, a, b)
|
33
32
|
return 0.0 if x <= 0.0
|
34
33
|
return 1.0 if x >= 1.0
|
35
|
-
Math::IncompleteBeta.axpy(1.0, 0.0, a,b,x)
|
34
|
+
Math::IncompleteBeta.axpy(1.0, 0.0, a, b, x)
|
36
35
|
end
|
37
36
|
|
38
37
|
# Inverse of the beta distribution function
|
39
|
-
def p_value(p,a,b, rmin=0, rmax=1)
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
38
|
+
def p_value(p, a, b, rmin = 0, rmax = 1)
|
39
|
+
fail 'a <= 0' if a <= 0
|
40
|
+
fail 'b <= 0' if b <= 0
|
41
|
+
fail 'rmin == rmax' if rmin == rmax
|
42
|
+
fail 'p <= 0' if p <= 0
|
43
|
+
fail 'p > 1' if p > 1
|
45
44
|
|
46
|
-
precision=8.88e-016
|
47
|
-
max_iterations=256
|
45
|
+
precision = 8.88e-016
|
46
|
+
max_iterations = 256
|
48
47
|
|
49
48
|
ga = 0
|
50
49
|
gb = 2
|
@@ -62,14 +61,13 @@ module Distribution
|
|
62
61
|
ga = guess
|
63
62
|
end
|
64
63
|
|
65
|
-
|
64
|
+
fail 'No value' if i == max_iterations
|
66
65
|
|
67
|
-
i+=1
|
66
|
+
i += 1
|
68
67
|
end
|
69
68
|
|
70
69
|
rmin + guess * (rmax - rmin)
|
71
70
|
end
|
72
|
-
|
73
71
|
end
|
74
72
|
end
|
75
73
|
end
|
@@ -2,27 +2,26 @@ require 'distribution/binomial/ruby'
|
|
2
2
|
require 'distribution/binomial/gsl'
|
3
3
|
require 'distribution/binomial/java'
|
4
4
|
module Distribution
|
5
|
-
|
6
5
|
# Calculate statisticals for Binomial Distribution.
|
7
6
|
module Binomial
|
8
|
-
SHORTHAND = 'bino'
|
9
|
-
|
7
|
+
SHORTHAND = 'bino'
|
8
|
+
|
10
9
|
extend Distributable
|
11
10
|
create_distribution_methods
|
12
|
-
|
11
|
+
|
13
12
|
##
|
14
13
|
# :singleton-method: pdf(x,k)
|
15
|
-
# Returns the integral of T distribution
|
16
|
-
# with +k+ degrees of freedom over [0, +x+]
|
14
|
+
# Returns the integral of T distribution
|
15
|
+
# with +k+ degrees of freedom over [0, +x+]
|
17
16
|
|
18
17
|
##
|
19
18
|
# :singleton-method: p_value(qn, k)
|
20
|
-
# Return the P-value of the corresponding integral +qn+ with
|
21
|
-
# +k+ degrees of freedom
|
22
|
-
|
19
|
+
# Return the P-value of the corresponding integral +qn+ with
|
20
|
+
# +k+ degrees of freedom
|
21
|
+
|
23
22
|
##
|
24
23
|
# :singleton-method: cdf(x,k)
|
25
|
-
# Returns the integral of T distribution
|
26
|
-
# with +k+ degrees of freedom over [0, +x+]
|
24
|
+
# Returns the integral of T distribution
|
25
|
+
# with +k+ degrees of freedom over [0, +x+]
|
27
26
|
end
|
28
27
|
end
|
@@ -2,13 +2,14 @@ module Distribution
|
|
2
2
|
module Binomial
|
3
3
|
module GSL_
|
4
4
|
class << self
|
5
|
-
def pdf(k,n,prob)
|
6
|
-
GSL::Ran.binomial_pdf(k,prob,n)
|
5
|
+
def pdf(k, n, prob)
|
6
|
+
GSL::Ran.binomial_pdf(k, prob, n)
|
7
7
|
end
|
8
|
-
|
9
|
-
|
8
|
+
|
9
|
+
def cdf(k, n, prob)
|
10
|
+
GSL::Cdf.binomial_P(k, prob, n)
|
10
11
|
end
|
11
12
|
end
|
12
13
|
end
|
13
14
|
end
|
14
|
-
end
|
15
|
+
end
|
@@ -2,30 +2,32 @@ module Distribution
|
|
2
2
|
module Binomial
|
3
3
|
module Ruby_
|
4
4
|
class << self
|
5
|
-
def pdf(k,n,pr)
|
6
|
-
|
7
|
-
Math.binomial_coefficient(n,k)*(pr**k)*(1-pr)**(n-k)
|
5
|
+
def pdf(k, n, pr)
|
6
|
+
fail 'k>n' if k > n
|
7
|
+
Math.binomial_coefficient(n, k) * (pr**k) * (1 - pr)**(n - k)
|
8
8
|
end
|
9
|
-
# TODO: Use exact_regularized_beta for
|
9
|
+
# TODO: Use exact_regularized_beta for
|
10
10
|
# small values and regularized_beta for bigger ones.
|
11
|
-
def cdf(k,n,pr)
|
12
|
-
#(0..x.floor).inject(0) {|ac,i| ac+pdf(i,n,pr)}
|
13
|
-
Math.regularized_beta(1-pr,n - k,k+1)
|
11
|
+
def cdf(k, n, pr)
|
12
|
+
# (0..x.floor).inject(0) {|ac,i| ac+pdf(i,n,pr)}
|
13
|
+
Math.regularized_beta(1 - pr, n - k, k + 1)
|
14
14
|
end
|
15
|
-
|
16
|
-
|
17
|
-
out=
|
18
|
-
|
15
|
+
|
16
|
+
def exact_cdf(k, n, pr)
|
17
|
+
out = (0..k).inject(0) { |ac, i| ac + pdf(i, n, pr) }
|
18
|
+
out = 1 if out > 1.0
|
19
|
+
out
|
19
20
|
end
|
20
|
-
|
21
|
-
|
21
|
+
|
22
|
+
def p_value(prob, n, pr)
|
23
|
+
ac = 0
|
22
24
|
(0..n).each do |i|
|
23
|
-
ac+=pdf(i,n,pr)
|
24
|
-
return i if prob<=ac
|
25
|
+
ac += pdf(i, n, pr)
|
26
|
+
return i if prob <= ac
|
25
27
|
end
|
26
28
|
end
|
27
|
-
|
28
|
-
|
29
|
+
|
30
|
+
alias_method :exact_pdf, :pdf
|
29
31
|
end
|
30
32
|
end
|
31
33
|
end
|
@@ -22,32 +22,34 @@ module Distribution
|
|
22
22
|
# Pr([x, \infty)) = y -> x
|
23
23
|
def pchi2(n, y)
|
24
24
|
if n == 1
|
25
|
-
|
26
|
-
|
27
|
-
w * w
|
25
|
+
w = Distribution::Normal.p_value(1 - y/2) # = p1.0-Distribution::Normal.cdf(y/2)
|
26
|
+
w * w
|
28
27
|
elsif n == 2
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
# v = (1.0 / y - 1.0) / 33.0
|
29
|
+
# newton_a(y, v) {|x| [q_chi2(n, x), -chi2dens(n, x)] }
|
30
|
+
-2.0 * Math.log(y)
|
32
31
|
else
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
32
|
+
eps = 1.0e-5
|
33
|
+
v = 0.0
|
34
|
+
s = 10.0
|
35
|
+
loop do
|
36
|
+
v += s
|
37
|
+
if s <= eps then break end
|
38
|
+
if (qe = q_chi2(n, v) - y) == 0.0 then break end
|
39
|
+
if qe < 0.0
|
40
|
+
v -= s
|
41
|
+
s /= 10.0
|
42
|
+
end
|
44
43
|
end
|
44
|
+
|
45
45
|
v
|
46
46
|
end
|
47
47
|
end
|
48
|
+
|
48
49
|
def p_value(pr,k)
|
49
50
|
pchi2(k, 1.0-pr)
|
50
51
|
end
|
52
|
+
|
51
53
|
def cdf(x,k)
|
52
54
|
1.0-q_chi2(k,x)
|
53
55
|
end
|
@@ -55,29 +57,32 @@ module Distribution
|
|
55
57
|
# chi-square distribution ([1])
|
56
58
|
# Integral over [x, \infty)
|
57
59
|
def q_chi2(df, chi2)
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
60
|
+
chi2 = chi2.to_f
|
61
|
+
if (df & 1) != 0
|
62
|
+
chi = Math.sqrt(chi2)
|
63
|
+
|
64
|
+
if (df == 1) then return 2 * (1.0-Distribution::Normal.cdf(chi)); end
|
65
|
+
s = t = chi * Math.exp(-0.5 * chi2) / SQ2PI
|
66
|
+
k = 3
|
67
|
+
|
68
|
+
while k < df
|
69
|
+
t *= chi2 / k; s += t;
|
70
|
+
k += 2
|
71
|
+
end
|
72
|
+
|
73
|
+
2 * (1.0-(Distribution::Normal.cdf(chi)) + s)
|
74
|
+
|
75
|
+
else
|
76
|
+
s = t = Math.exp(-0.5 * chi2)
|
77
|
+
k = 2
|
78
|
+
|
79
|
+
while k < df
|
80
|
+
t *= chi2 / k; s += t;
|
81
|
+
k += 2
|
82
|
+
end
|
83
|
+
s
|
84
|
+
end
|
78
85
|
end
|
79
|
-
|
80
|
-
|
81
86
|
end
|
82
87
|
end
|
83
88
|
end
|
data/lib/distribution/f.rb
CHANGED
@@ -4,26 +4,25 @@ require 'distribution/f/statistics2'
|
|
4
4
|
require 'distribution/f/java'
|
5
5
|
module Distribution
|
6
6
|
# Calculate cdf and inverse cdf for F Distribution.
|
7
|
-
#
|
7
|
+
#
|
8
8
|
module F
|
9
|
-
SHORTHAND='fdist'
|
9
|
+
SHORTHAND='fdist'
|
10
10
|
extend Distributable
|
11
11
|
create_distribution_methods
|
12
|
-
|
12
|
+
|
13
13
|
##
|
14
14
|
# :singleton-method: pdf(x,k1,k2)
|
15
|
-
# Returns the PDF of F distribution
|
16
|
-
# with +k1+ and +k2+ degrees of freedom over [0, +x+]
|
15
|
+
# Returns the PDF of F distribution
|
16
|
+
# with +k1+ and +k2+ degrees of freedom over [0, +x+]
|
17
17
|
|
18
18
|
##
|
19
19
|
# :singleton-method: p_value(qn, k1, k2)
|
20
|
-
# Return the P-value of the corresponding integral +qn+ with
|
21
|
-
# +k1+ and +k2+ degrees of freedom
|
22
|
-
|
20
|
+
# Return the P-value of the corresponding integral +qn+ with
|
21
|
+
# +k1+ and +k2+ degrees of freedom
|
22
|
+
|
23
23
|
##
|
24
24
|
# :singleton-method: cdf(x,k1,k2)
|
25
|
-
# Returns the integral of F distribution
|
26
|
-
# with +k1+ and +k2+ degrees of freedom over [0, +x+]
|
27
|
-
|
25
|
+
# Returns the integral of F distribution
|
26
|
+
# with +k1+ and +k2+ degrees of freedom over [0, +x+]
|
28
27
|
end
|
29
28
|
end
|
data/lib/distribution/f/ruby.rb
CHANGED
@@ -1,116 +1,118 @@
|
|
1
1
|
module Distribution
|
2
2
|
module F
|
3
|
+
# Continuous random number distributions are defined by a probability density function, p(x), such that the probability of x occurring in the infinitesimal range x to x+dx is p dx.
|
4
|
+
|
5
|
+
# The cumulative distribution function for the lower tail P(x) is defined by the integral,
|
6
|
+
|
7
|
+
# P(x) = \int_{-\infty}^{x} dx' p(x')
|
8
|
+
# and gives the probability of a variate taking a value less than x.
|
9
|
+
|
10
|
+
# The cumulative distribution function for the upper tail Q(x) is defined by the integral,
|
11
|
+
|
12
|
+
# Q(x) = \int_{x}^{+\infty} dx' p(x')
|
13
|
+
# and gives the probability of a variate taking a value greater than x.
|
14
|
+
|
15
|
+
# The upper and lower cumulative distribution functions are related by P(x) + Q(x) = 1 and satisfy 0 <= P(x) <= 1, 0 <= Q(x).
|
3
16
|
module Ruby_
|
4
|
-
|
17
|
+
extend Distribution::MathExtension
|
5
18
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
cos2 = 1.0 / (1.0 + df1.to_f * f / df2.to_f)
|
20
|
-
sin2 = 1.0 - cos2
|
21
|
-
|
22
|
-
if (df1 % 2 == 0)
|
23
|
-
prob = cos2 ** (df2.to_f / 2.0)
|
24
|
-
temp = prob
|
25
|
-
i = 2
|
26
|
-
while i < df1
|
27
|
-
temp *= (df2.to_f + i - 2) * sin2 / i
|
28
|
-
prob += temp
|
29
|
-
i += 2
|
30
|
-
end
|
31
|
-
return prob
|
32
|
-
end
|
33
|
-
prob = Math.atan(Math.sqrt(df2.to_f / (df1.to_f * f)))
|
34
|
-
temp = Math.sqrt(sin2 * cos2)
|
35
|
-
i = 3
|
36
|
-
while i <= df1
|
37
|
-
prob += temp
|
38
|
-
temp *= (i - 1).to_f * sin2 / i.to_f;
|
39
|
-
i += 2.0
|
40
|
-
end
|
41
|
-
temp *= df1.to_f
|
42
|
-
i = 3
|
43
|
-
while i <= df2
|
44
|
-
prob -= temp
|
45
|
-
temp *= (df1.to_f + i - 2) * cos2 / i.to_f
|
46
|
-
i += 2
|
47
|
-
end
|
48
|
-
prob * 2.0 / Math::PI
|
49
|
-
end
|
19
|
+
# functions needed:
|
20
|
+
# - pdf
|
21
|
+
# - cdf (lower cumulative function, P(x))
|
22
|
+
# - Q(x), upper cumulative function
|
23
|
+
# - mean
|
24
|
+
# - mode
|
25
|
+
# - kurtosis
|
26
|
+
# - skewness
|
27
|
+
# - entropy
|
28
|
+
# - "fit" (maximum likelihood?)
|
29
|
+
# - expected value (given a function)
|
30
|
+
# - lower-tail quantile -> P
|
31
|
+
# - upper tail quantile -> Q
|
50
32
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
33
|
+
class << self
|
34
|
+
# F Distribution (Ruby) -- Probability Density Function
|
35
|
+
def pdf(x, n, m)
|
36
|
+
x = x.to_f
|
37
|
+
numerator = ((n * x)**n * (m**m)) / (n * x + m)**(n + m)
|
38
|
+
denominator = x * Math.beta(n / 2.0, m / 2.0)
|
55
39
|
|
56
|
-
|
57
|
-
|
58
|
-
def pf(q, n1, n2)
|
59
|
-
if(q < 0.0 || q > 1.0 || n1 < 1 || n2 < 1)
|
60
|
-
$stderr.printf("Error : Illegal parameter in pf()!\n")
|
61
|
-
return 0.0
|
62
|
-
end
|
40
|
+
Math.sqrt(numerator) / denominator
|
41
|
+
end
|
63
42
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
fw += s
|
71
|
-
if s <= eps then return fw end
|
72
|
-
if (qe = q_f(n1, n2, fw) - q) == 0.0 then return fw end
|
73
|
-
if qe < 0.0
|
74
|
-
fw -= s
|
75
|
-
s /= 10.0 #/
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
43
|
+
# Cumulative Distribution Function.
|
44
|
+
def cdf(x, n, m)
|
45
|
+
x = x.to_f
|
46
|
+
xx = (x * n).to_f / (x * n + m).to_f
|
47
|
+
regularized_beta(xx, n / 2.0, m / 2.0)
|
48
|
+
end
|
79
49
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
50
|
+
# Upper cumulative function.
|
51
|
+
#
|
52
|
+
# If cdf(x, n, m) = p, then q(x, n, m) = 1 - p
|
53
|
+
def q(x, n, m)
|
54
|
+
1.0 - cdf(x, n, m)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Return the F value corresponding to `probability` with degrees of
|
58
|
+
# freedom `n` and `m`.
|
59
|
+
#
|
60
|
+
# If x = quantile(p, n, m), then cdf(x, n, m) = p.
|
61
|
+
#
|
62
|
+
# Taken from:
|
63
|
+
# https://github.com/JuliaLang/Rmath-julia/blob/master/src/qf.c
|
64
|
+
def p_value(probability, n, m)
|
65
|
+
return Float::NAN if n <= 0.0 || m <= 0.0
|
66
|
+
|
67
|
+
if n == Float::INFINITY || n == -Float::INFINITY || m == Float::INFINITY || m == -Float::INFINITY
|
68
|
+
return 1.0
|
69
|
+
end
|
70
|
+
|
71
|
+
if n <= m && m > 4e5
|
72
|
+
return Distribution::ChiSquare.p_value(probability, n) / n.to_f
|
73
|
+
elsif n > 4e5 # thus n > m
|
74
|
+
return m.to_f / Distribution::ChiSquare.p_value(1.0 - probability, m)
|
75
|
+
else
|
76
|
+
# O problema está aqui.
|
77
|
+
tmp = Distribution::Beta.p_value(1.0 - probability, m.to_f / 2, n.to_f / 2)
|
78
|
+
value = (1.0 / tmp - 1.0) * (m.to_f / n.to_f)
|
79
|
+
return value.nan? ? Float::NAN : value
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Complementary quantile function.
|
84
|
+
#
|
85
|
+
# def cquantile(prob, n, m)
|
86
|
+
# quantile(1.0 - probability, n, m)
|
87
|
+
# end
|
88
|
+
|
89
|
+
# Return the corresponding F value for a p-value `y` with `n` and `m`
|
90
|
+
# degrees of freedom.
|
91
|
+
#
|
92
|
+
# @param y [Float] Value corresponding to the desired p-value. Between 0 and 1.
|
93
|
+
# @param n [Float] Degree of freedom of the first random variable.
|
94
|
+
# @param m [Float] Degree of freedom of the second random variable.
|
95
|
+
# @return [Float] Value of the F distribution that gives a p-value of `y`.
|
96
|
+
|
97
|
+
def mean
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
def mode
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
def skewness
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
def kurtosis
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
def entropy
|
114
|
+
|
115
|
+
end
|
114
116
|
end
|
115
117
|
end
|
116
118
|
end
|
data/lib/distribution/version.rb
CHANGED
data/spec/chisquare_spec.rb
CHANGED
data/spec/f_spec.rb
CHANGED
@@ -1,107 +1,109 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__)+
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper.rb')
|
2
2
|
|
3
3
|
include ExampleWithGSL
|
4
4
|
|
5
5
|
describe Distribution::F do
|
6
|
-
shared_examples_for
|
7
|
-
|
8
|
-
|
6
|
+
shared_examples_for 'F engine (with rng)' do
|
7
|
+
it 'should return correct rng' do
|
8
|
+
pending
|
9
|
+
end
|
9
10
|
end
|
10
|
-
end
|
11
11
|
|
12
|
-
shared_examples_for
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
12
|
+
shared_examples_for 'F engine (with pdf)' do
|
13
|
+
it_only_with_gsl 'should return correct pdf' do
|
14
|
+
if @engine.respond_to? :pdf
|
15
|
+
[0.1, 0.5, 1, 2, 10, 20, 30].each do |x|
|
16
|
+
[2, 5, 10].product([2, 5, 10]).each do |n, m|
|
17
|
+
expected_value = GSL::Ran.fdist_pdf(x, n, m)
|
18
|
+
@engine.pdf(x, n, m).should be_within(1e-4).of(expected_value)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
else
|
22
|
+
pending("No #{@engine}.pdf")
|
23
|
+
end
|
24
24
|
end
|
25
25
|
end
|
26
|
-
end
|
27
26
|
|
28
|
-
shared_examples_for
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
pending("No #{@engine}.cdf")
|
27
|
+
shared_examples_for 'F engine' do
|
28
|
+
it_only_with_gsl 'should return correct cdf' do
|
29
|
+
if @engine.respond_to? :cdf
|
30
|
+
[0.1, 0.5, 1, 2, 10, 20, 30].each do |f|
|
31
|
+
[2, 5, 10].each do |n2|
|
32
|
+
[2, 5, 10].each do |n1|
|
33
|
+
@engine.cdf(f, n1, n2).should be_within(1e-4).of(GSL::Cdf.fdist_P(f, n1, n2))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
else
|
38
|
+
pending("No #{@engine}.cdf")
|
39
|
+
end
|
42
40
|
end
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
41
|
+
|
42
|
+
it_only_with_gsl 'should return correct p_value', focus: true do
|
43
|
+
if @engine.respond_to? :p_value
|
44
|
+
|
45
|
+
expected_value = GSL::Cdf.fdist_Pinv(0.975, 5, 4.189092917592713)
|
46
|
+
@engine.p_value(0.975, 5, 4.189092917592713).should be_within(1e-4).of(expected_value)
|
47
|
+
|
48
|
+
[0.1, 0.5, 1, 2, 10, 20, 30].each do |f|
|
49
|
+
[2, 5, 10].each do |n2|
|
50
|
+
[2, 5, 10].each do |n1|
|
51
|
+
area = @engine.cdf(f, n1, n2)
|
52
|
+
expected_value = GSL::Cdf.fdist_Pinv(area, n1, n2)
|
53
|
+
|
54
|
+
@engine.p_value(area, n1, n2).should be_within(1e-4).of(expected_value)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
else
|
59
|
+
pending("No #{@engine}.p_value")
|
60
|
+
end
|
60
61
|
end
|
61
62
|
end
|
62
|
-
end
|
63
63
|
|
64
|
-
describe
|
64
|
+
describe 'singleton' do
|
65
65
|
before do
|
66
|
-
@engine=Distribution::F
|
66
|
+
@engine = Distribution::F
|
67
67
|
end
|
68
|
-
|
69
|
-
it_should_behave_like
|
68
|
+
|
69
|
+
it_should_behave_like 'F engine'
|
70
|
+
it_should_behave_like 'F engine (with pdf)'
|
70
71
|
end
|
71
|
-
|
72
|
+
|
72
73
|
describe Distribution::F::Ruby_ do
|
73
74
|
before do
|
74
|
-
@engine=Distribution::F::Ruby_
|
75
|
+
@engine = Distribution::F::Ruby_
|
75
76
|
end
|
76
|
-
it_should_behave_like
|
77
|
-
it_should_behave_like
|
77
|
+
it_should_behave_like 'F engine'
|
78
|
+
it_should_behave_like 'F engine (with pdf)'
|
78
79
|
end
|
80
|
+
|
79
81
|
if Distribution.has_gsl?
|
80
82
|
describe Distribution::F::GSL_ do
|
81
83
|
before do
|
82
|
-
@engine=Distribution::F::GSL_
|
84
|
+
@engine = Distribution::F::GSL_
|
83
85
|
end
|
84
|
-
|
85
|
-
|
86
|
+
it_should_behave_like 'F engine'
|
87
|
+
it_should_behave_like 'F engine (with pdf)'
|
86
88
|
end
|
87
|
-
end
|
89
|
+
end
|
90
|
+
|
88
91
|
if Distribution.has_statistics2?
|
89
92
|
describe Distribution::F::Statistics2_ do
|
90
93
|
before do
|
91
|
-
@engine=Distribution::F::Statistics2_
|
94
|
+
@engine = Distribution::F::Statistics2_
|
92
95
|
end
|
93
|
-
|
94
|
-
end
|
96
|
+
it_should_behave_like 'F engine'
|
97
|
+
end
|
95
98
|
end
|
96
|
-
|
99
|
+
|
97
100
|
if Distribution.has_java?
|
98
101
|
describe Distribution::F::Java_ do
|
99
102
|
before do
|
100
|
-
@engine=Distribution::F::Java_
|
103
|
+
@engine = Distribution::F::Java_
|
101
104
|
end
|
102
|
-
|
103
|
-
|
104
|
-
end
|
105
|
+
it_should_behave_like 'F engine'
|
106
|
+
it_should_behave_like 'F engine (with pdf)'
|
107
|
+
end
|
105
108
|
end
|
106
|
-
|
107
109
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: distribution
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Claudio Bustos
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-05-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -188,7 +188,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
188
188
|
version: '0'
|
189
189
|
requirements: []
|
190
190
|
rubyforge_project:
|
191
|
-
rubygems_version: 2.
|
191
|
+
rubygems_version: 2.4.5
|
192
192
|
signing_key:
|
193
193
|
specification_version: 4
|
194
194
|
summary: Distribution
|