distribution 0.7.2 → 0.7.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.
- 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
|