distribution 0.6.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/.travis.yml +13 -0
- data/.yardopts +5 -0
- data/Gemfile +5 -0
- data/History.txt +24 -8
- data/LICENCE.md +26 -0
- data/README.md +155 -0
- data/Rakefile +15 -19
- data/benchmark/binomial_coefficient.rb +19 -23
- data/benchmark/binomial_coefficient/experiment.rb +33 -36
- data/benchmark/factorial_hash.rb +7 -8
- data/benchmark/factorial_method.rb +4 -6
- data/benchmark/odd.rb +6 -7
- data/benchmark/power.rb +11 -11
- data/bin/distribution +26 -26
- data/data/template/spec.erb +7 -6
- data/distribution.gemspec +25 -0
- data/lib/distribution.rb +79 -124
- data/lib/distribution/beta.rb +6 -8
- data/lib/distribution/beta/gsl.rb +14 -9
- data/lib/distribution/beta/java.rb +1 -1
- data/lib/distribution/beta/ruby.rb +41 -7
- 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 +22 -15
- data/lib/distribution/bivariatenormal.rb +4 -5
- data/lib/distribution/bivariatenormal/gsl.rb +2 -2
- data/lib/distribution/bivariatenormal/java.rb +1 -1
- data/lib/distribution/bivariatenormal/ruby.rb +245 -254
- data/lib/distribution/chisquare.rb +8 -10
- data/lib/distribution/chisquare/gsl.rb +24 -19
- data/lib/distribution/chisquare/java.rb +1 -1
- data/lib/distribution/chisquare/ruby.rb +60 -55
- data/lib/distribution/chisquare/statistics2.rb +16 -13
- data/lib/distribution/distributable.rb +40 -0
- data/lib/distribution/exponential.rb +4 -5
- data/lib/distribution/exponential/gsl.rb +13 -9
- data/lib/distribution/exponential/ruby.rb +17 -11
- data/lib/distribution/f.rb +10 -11
- data/lib/distribution/f/gsl.rb +26 -22
- data/lib/distribution/f/java.rb +1 -1
- data/lib/distribution/f/ruby.rb +104 -105
- data/lib/distribution/f/statistics2.rb +22 -19
- data/lib/distribution/gamma.rb +5 -7
- data/lib/distribution/gamma/gsl.rb +13 -9
- data/lib/distribution/gamma/java.rb +1 -1
- data/lib/distribution/gamma/ruby.rb +5 -11
- data/lib/distribution/hypergeometric.rb +5 -8
- data/lib/distribution/hypergeometric/gsl.rb +5 -6
- data/lib/distribution/hypergeometric/java.rb +1 -1
- data/lib/distribution/hypergeometric/ruby.rb +34 -35
- data/lib/distribution/logistic.rb +6 -9
- data/lib/distribution/logistic/ruby.rb +14 -9
- data/lib/distribution/lognormal.rb +37 -0
- data/lib/distribution/lognormal/gsl.rb +21 -0
- data/lib/distribution/lognormal/ruby.rb +16 -0
- data/lib/distribution/math_extension.rb +187 -231
- data/lib/distribution/math_extension/chebyshev_series.rb +281 -272
- data/lib/distribution/math_extension/erfc.rb +28 -31
- data/lib/distribution/math_extension/exponential_integral.rb +17 -17
- data/lib/distribution/math_extension/gammastar.rb +19 -20
- data/lib/distribution/math_extension/gsl_utilities.rb +12 -12
- data/lib/distribution/math_extension/incomplete_beta.rb +52 -61
- data/lib/distribution/math_extension/incomplete_gamma.rb +166 -168
- data/lib/distribution/math_extension/log_utilities.rb +20 -22
- data/lib/distribution/normal.rb +11 -13
- data/lib/distribution/normal/gsl.rb +13 -10
- data/lib/distribution/normal/java.rb +30 -1
- data/lib/distribution/normal/ruby.rb +69 -59
- data/lib/distribution/normal/statistics2.rb +5 -2
- data/lib/distribution/normalmultivariate.rb +64 -64
- data/lib/distribution/poisson.rb +12 -14
- data/lib/distribution/poisson/gsl.rb +7 -7
- data/lib/distribution/poisson/java.rb +26 -0
- data/lib/distribution/poisson/ruby.rb +38 -9
- data/lib/distribution/shorthand.rb +17 -0
- data/lib/distribution/t.rb +16 -16
- data/lib/distribution/t/gsl.rb +27 -24
- data/lib/distribution/t/java.rb +1 -1
- data/lib/distribution/t/ruby.rb +99 -100
- data/lib/distribution/t/statistics2.rb +19 -19
- data/lib/distribution/uniform.rb +26 -0
- data/lib/distribution/uniform/gsl.rb +36 -0
- data/lib/distribution/uniform/ruby.rb +91 -0
- data/lib/distribution/version.rb +3 -0
- data/lib/distribution/weibull.rb +10 -0
- data/lib/distribution/weibull/gsl.rb +21 -0
- data/lib/distribution/weibull/ruby.rb +34 -0
- data/spec/beta_spec.rb +48 -50
- data/spec/binomial_spec.rb +80 -84
- data/spec/bivariatenormal_spec.rb +28 -35
- data/spec/chisquare_spec.rb +49 -52
- data/spec/distribution_spec.rb +11 -11
- data/spec/exponential_spec.rb +48 -39
- data/spec/f_spec.rb +73 -71
- data/spec/gamma_spec.rb +50 -53
- data/spec/hypergeometric_spec.rb +63 -69
- data/spec/logistic_spec.rb +31 -37
- data/spec/lognormal_spec.rb +54 -0
- data/spec/math_extension_spec.rb +192 -209
- data/spec/normal_spec.rb +80 -73
- data/spec/poisson_spec.rb +78 -36
- data/spec/shorthand_spec.rb +19 -22
- data/spec/spec_helper.rb +31 -6
- data/spec/t_spec.rb +63 -77
- data/spec/uniform_spec.rb +154 -0
- data/spec/weibull_spec.rb +17 -0
- data/vendor/java/commons-math-2.2.jar +0 -0
- metadata +91 -111
- data.tar.gz.sig +0 -0
- data/.autotest +0 -23
- data/.gemtest +0 -0
- data/Manifest.txt +0 -95
- data/README.txt +0 -100
- metadata.gz.sig +0 -0
@@ -4,27 +4,25 @@ require 'distribution/chisquare/statistics2'
|
|
4
4
|
require 'distribution/chisquare/java'
|
5
5
|
module Distribution
|
6
6
|
# Calculate cdf and inverse cdf for Chi Square Distribution.
|
7
|
-
#
|
7
|
+
#
|
8
8
|
module ChiSquare
|
9
9
|
extend Distributable
|
10
|
-
SHORTHAND='chisq'
|
10
|
+
SHORTHAND = 'chisq'
|
11
11
|
create_distribution_methods
|
12
|
-
|
12
|
+
|
13
13
|
##
|
14
14
|
# :singleton-method: pdf(x)
|
15
|
-
# Returns PDF of of Chi-squared distribution
|
15
|
+
# Returns PDF of of Chi-squared distribution
|
16
16
|
# with +k+ degrees of freedom
|
17
|
-
|
18
|
-
|
17
|
+
|
19
18
|
##
|
20
19
|
# :singleton-method: cdf(x,k)
|
21
|
-
# Returns the integral of Chi-squared distribution
|
22
|
-
# with +k+ degrees of freedom over [0, +x+]
|
20
|
+
# Returns the integral of Chi-squared distribution
|
21
|
+
# with +k+ degrees of freedom over [0, +x+]
|
23
22
|
|
24
23
|
##
|
25
24
|
# :singleton-method: p_value(qn, k)
|
26
|
-
# Return the P-value of the corresponding integral +qn+ with
|
25
|
+
# Return the P-value of the corresponding integral +qn+ with
|
27
26
|
# +k+ degrees of freedom
|
28
|
-
|
29
27
|
end
|
30
28
|
end
|
@@ -2,25 +2,30 @@ module Distribution
|
|
2
2
|
module ChiSquare
|
3
3
|
module GSL_
|
4
4
|
class << self
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
5
|
+
def rng(_k, _seed = nil)
|
6
|
+
nil
|
7
|
+
end
|
8
|
+
|
9
|
+
def pdf(x, k)
|
10
|
+
GSL::Ran.chisq_pdf(x.to_f, k.to_i)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Chi-square cumulative distribution function (cdf).
|
14
|
+
#
|
15
|
+
# Returns the integral of Chi-squared distribution
|
16
|
+
# with k degrees of freedom over [0, x]
|
17
|
+
#
|
18
|
+
def cdf(x, k)
|
19
|
+
GSL::Cdf.chisq_P(x.to_f, k.to_i)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Return the P-value of the corresponding integral with
|
23
|
+
# k degrees of freedom
|
24
|
+
def quantile(pr, k)
|
25
|
+
GSL::Cdf.chisq_Pinv(pr.to_f, k.to_i)
|
26
|
+
end
|
27
|
+
|
28
|
+
alias_method :p_value, :quantile
|
24
29
|
end
|
25
30
|
end
|
26
31
|
end
|
@@ -2,82 +2,87 @@ module Distribution
|
|
2
2
|
module ChiSquare
|
3
3
|
module Ruby_
|
4
4
|
class << self
|
5
|
-
|
6
5
|
include Math
|
7
|
-
def pdf(x,n)
|
6
|
+
def pdf(x, n)
|
8
7
|
if n == 1
|
9
|
-
1.0/Math.sqrt(2 * Math::PI * x) * Math::E**(-x/2.0)
|
8
|
+
1.0 / Math.sqrt(2 * Math::PI * x) * Math::E**(-x / 2.0)
|
10
9
|
elsif n == 2
|
11
|
-
0.5 * Math::E**(-x/2.0)
|
10
|
+
0.5 * Math::E**(-x / 2.0)
|
12
11
|
else
|
13
12
|
n = n.to_f
|
14
|
-
n2 = n/2
|
13
|
+
n2 = n / 2
|
15
14
|
x = x.to_f
|
16
|
-
1.0 / 2**n2 / gamma(n2) * x**(n2 - 1.0) * Math.exp(-x/2.0)
|
17
|
-
end
|
15
|
+
1.0 / 2**n2 / gamma(n2) * x**(n2 - 1.0) * Math.exp(-x / 2.0)
|
16
|
+
end
|
18
17
|
end
|
19
|
-
|
20
|
-
|
18
|
+
|
21
19
|
# CDF Inverse over [x, \infty)
|
22
20
|
# Pr([x, \infty)) = y -> x
|
23
21
|
def pchi2(n, y)
|
24
22
|
if n == 1
|
25
|
-
|
26
|
-
|
27
|
-
w * w
|
23
|
+
w = Distribution::Normal.p_value(1 - y / 2) # = p1.0-Distribution::Normal.cdf(y/2)
|
24
|
+
w * w
|
28
25
|
elsif n == 2
|
29
|
-
|
30
|
-
|
31
|
-
|
26
|
+
# v = (1.0 / y - 1.0) / 33.0
|
27
|
+
# newton_a(y, v) {|x| [q_chi2(n, x), -chi2dens(n, x)] }
|
28
|
+
-2.0 * Math.log(y)
|
32
29
|
else
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
30
|
+
eps = 1.0e-5
|
31
|
+
v = 0.0
|
32
|
+
s = 10.0
|
33
|
+
loop do
|
34
|
+
v += s
|
35
|
+
break if s <= eps
|
36
|
+
if (qe = q_chi2(n, v) - y) == 0.0 then break end
|
37
|
+
if qe < 0.0
|
38
|
+
v -= s
|
39
|
+
s /= 10.0
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
v
|
44
44
|
end
|
45
|
-
v
|
46
|
-
end
|
47
|
-
end
|
48
|
-
def p_value(pr,k)
|
49
|
-
pchi2(k, 1.0-pr)
|
50
45
|
end
|
51
|
-
|
52
|
-
|
46
|
+
|
47
|
+
def cdf(x, k)
|
48
|
+
1.0 - q_chi2(k, x)
|
53
49
|
end
|
54
|
-
|
50
|
+
|
55
51
|
# chi-square distribution ([1])
|
56
52
|
# Integral over [x, \infty)
|
57
53
|
def q_chi2(df, chi2)
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
54
|
+
chi2 = chi2.to_f
|
55
|
+
if (df & 1) != 0
|
56
|
+
chi = Math.sqrt(chi2)
|
57
|
+
|
58
|
+
return 2 * (1.0 - Distribution::Normal.cdf(chi)) if (df == 1)
|
59
|
+
s = t = chi * Math.exp(-0.5 * chi2) / SQ2PI
|
60
|
+
k = 3
|
61
|
+
|
62
|
+
while k < df
|
63
|
+
t *= chi2 / k; s += t
|
64
|
+
k += 2
|
65
|
+
end
|
66
|
+
|
67
|
+
2 * (1.0 - (Distribution::Normal.cdf(chi)) + s)
|
68
|
+
|
69
|
+
else
|
70
|
+
s = t = Math.exp(-0.5 * chi2)
|
71
|
+
k = 2
|
72
|
+
|
73
|
+
while k < df
|
74
|
+
t *= chi2 / k; s += t
|
75
|
+
k += 2
|
76
|
+
end
|
77
|
+
s
|
78
|
+
end
|
77
79
|
end
|
80
|
+
|
81
|
+
def quantile(pr, k)
|
82
|
+
pchi2(k, 1.0 - pr)
|
78
83
|
end
|
79
|
-
|
80
|
-
|
84
|
+
|
85
|
+
alias_method :p_value, :quantile
|
81
86
|
end
|
82
87
|
end
|
83
88
|
end
|
@@ -2,20 +2,23 @@ module Distribution
|
|
2
2
|
module ChiSquare
|
3
3
|
module Statistics2_
|
4
4
|
class << self
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
5
|
+
# Chi-square cumulative distribution function (cdf).
|
6
|
+
#
|
7
|
+
# Returns the integral of Chi-squared distribution
|
8
|
+
# with k degrees of freedom over [0, x]
|
9
|
+
#
|
10
|
+
def cdf(x, k)
|
11
|
+
Statistics2.chi2dist(k.to_i, x)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Return the P-value of the corresponding integral with
|
15
|
+
# k degrees of freedom
|
16
|
+
def quantile(pr, k)
|
17
|
+
Statistics2.pchi2X_(k.to_i, pr)
|
18
|
+
end
|
19
|
+
|
20
|
+
alias_method :p_value, :quantile
|
17
21
|
end
|
18
22
|
end
|
19
23
|
end
|
20
|
-
end
|
21
24
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Distribution
|
2
|
+
# Magic module
|
3
|
+
module Distributable #:nodoc:
|
4
|
+
# Create methods for each module and add methods to
|
5
|
+
# Distribution::Shorthand.
|
6
|
+
#
|
7
|
+
# Traverse Distribution.libraries_order adding
|
8
|
+
# methods availables for each engine module on
|
9
|
+
# the current library
|
10
|
+
#
|
11
|
+
# Kids: Metaprogramming trickery! Don't do at work.
|
12
|
+
# This section was created between a very long reunion
|
13
|
+
# and a 456 Km. travel
|
14
|
+
def create_distribution_methods
|
15
|
+
Distribution.libraries_order.each do |l_name|
|
16
|
+
if const_defined? l_name
|
17
|
+
l = const_get(l_name)
|
18
|
+
# Add methods from engine to base base, if not yet included
|
19
|
+
l.singleton_methods.each do |m|
|
20
|
+
unless singleton_methods.include? m
|
21
|
+
define_method(m) do |*args|
|
22
|
+
l.send(m, *args)
|
23
|
+
end
|
24
|
+
# Add method to Distribution::Shorthand
|
25
|
+
sh = const_get(:SHORTHAND)
|
26
|
+
Distribution::Shorthand.add_shortcut(sh, m) do |*args|
|
27
|
+
l.send(m, *args)
|
28
|
+
end
|
29
|
+
|
30
|
+
module_function m
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# create alias for common methods
|
37
|
+
alias_method :inverse_cdf, :p_value if singleton_methods.include? :p_value
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,19 +1,18 @@
|
|
1
1
|
require 'distribution/exponential/ruby'
|
2
2
|
require 'distribution/exponential/gsl'
|
3
|
-
#require 'distribution/exponential/java'
|
4
|
-
|
3
|
+
# require 'distribution/exponential/java'
|
5
4
|
|
6
5
|
module Distribution
|
7
6
|
# From Wikipedia:
|
8
|
-
# In probability theory and statistics, the exponential distribution
|
7
|
+
# In probability theory and statistics, the exponential distribution
|
9
8
|
# (a.k.a. negative exponential distribution) is a family of continuous
|
10
9
|
# probability distributions. It describes the time between events in a
|
11
|
-
# Poisson process, i.e. a process in which events occur continuously
|
10
|
+
# Poisson process, i.e. a process in which events occur continuously
|
12
11
|
# and independently at a constant average rate.
|
13
12
|
#
|
14
13
|
# Parameter +l+ is the rate parameter, the number of occurrences/unit time.
|
15
14
|
module Exponential
|
16
|
-
SHORTHAND='expo'
|
15
|
+
SHORTHAND = 'expo'
|
17
16
|
extend Distributable
|
18
17
|
create_distribution_methods
|
19
18
|
##
|
@@ -2,18 +2,22 @@ module Distribution
|
|
2
2
|
module Exponential
|
3
3
|
module GSL_
|
4
4
|
class << self
|
5
|
-
def pdf(x,l)
|
6
|
-
return 0 if x<0
|
7
|
-
GSL::Ran.exponential_pdf(x,1/l.to_f)
|
5
|
+
def pdf(x, l)
|
6
|
+
return 0 if x < 0
|
7
|
+
GSL::Ran.exponential_pdf(x, 1 / l.to_f)
|
8
8
|
end
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
|
10
|
+
def cdf(x, l)
|
11
|
+
return 0 if x < 0
|
12
|
+
GSL::Cdf.exponential_P(x, 1 / l.to_f)
|
12
13
|
end
|
13
|
-
|
14
|
-
|
14
|
+
|
15
|
+
def quantile(pr, l)
|
16
|
+
GSL::Cdf.exponential_Pinv(pr, 1 / l.to_f)
|
15
17
|
end
|
18
|
+
|
19
|
+
alias_method :p_value, :quantile
|
16
20
|
end
|
17
21
|
end
|
18
22
|
end
|
19
|
-
end
|
23
|
+
end
|
@@ -2,20 +2,26 @@ module Distribution
|
|
2
2
|
module Exponential
|
3
3
|
module Ruby_
|
4
4
|
class << self
|
5
|
-
def rng(l)
|
6
|
-
|
7
|
-
|
8
|
-
def pdf(x,l)
|
9
|
-
return 0 if x<0
|
10
|
-
l*Math.exp(-l*x)
|
5
|
+
def rng(l, opts = {})
|
6
|
+
rng = opts[:random] || Random
|
7
|
+
-> { p_value(rng.rand, l) }
|
11
8
|
end
|
12
|
-
|
13
|
-
|
14
|
-
|
9
|
+
|
10
|
+
def pdf(x, l)
|
11
|
+
return 0 if x < 0
|
12
|
+
l * Math.exp(-l * x)
|
15
13
|
end
|
16
|
-
|
17
|
-
|
14
|
+
|
15
|
+
def cdf(x, l)
|
16
|
+
return 0 if x < 0
|
17
|
+
1 - Math.exp(-l * x)
|
18
18
|
end
|
19
|
+
|
20
|
+
def quantile(pr, l)
|
21
|
+
(-Math.log(1 - pr)).quo(l)
|
22
|
+
end
|
23
|
+
|
24
|
+
alias_method :p_value, :quantile
|
19
25
|
end
|
20
26
|
end
|
21
27
|
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
|