distribution 0.6.0 → 0.8.0

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.
Files changed (117) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.travis.yml +13 -0
  4. data/.yardopts +5 -0
  5. data/Gemfile +5 -0
  6. data/History.txt +24 -8
  7. data/LICENCE.md +26 -0
  8. data/README.md +155 -0
  9. data/Rakefile +15 -19
  10. data/benchmark/binomial_coefficient.rb +19 -23
  11. data/benchmark/binomial_coefficient/experiment.rb +33 -36
  12. data/benchmark/factorial_hash.rb +7 -8
  13. data/benchmark/factorial_method.rb +4 -6
  14. data/benchmark/odd.rb +6 -7
  15. data/benchmark/power.rb +11 -11
  16. data/bin/distribution +26 -26
  17. data/data/template/spec.erb +7 -6
  18. data/distribution.gemspec +25 -0
  19. data/lib/distribution.rb +79 -124
  20. data/lib/distribution/beta.rb +6 -8
  21. data/lib/distribution/beta/gsl.rb +14 -9
  22. data/lib/distribution/beta/java.rb +1 -1
  23. data/lib/distribution/beta/ruby.rb +41 -7
  24. data/lib/distribution/binomial.rb +10 -11
  25. data/lib/distribution/binomial/gsl.rb +6 -5
  26. data/lib/distribution/binomial/java.rb +1 -1
  27. data/lib/distribution/binomial/ruby.rb +22 -15
  28. data/lib/distribution/bivariatenormal.rb +4 -5
  29. data/lib/distribution/bivariatenormal/gsl.rb +2 -2
  30. data/lib/distribution/bivariatenormal/java.rb +1 -1
  31. data/lib/distribution/bivariatenormal/ruby.rb +245 -254
  32. data/lib/distribution/chisquare.rb +8 -10
  33. data/lib/distribution/chisquare/gsl.rb +24 -19
  34. data/lib/distribution/chisquare/java.rb +1 -1
  35. data/lib/distribution/chisquare/ruby.rb +60 -55
  36. data/lib/distribution/chisquare/statistics2.rb +16 -13
  37. data/lib/distribution/distributable.rb +40 -0
  38. data/lib/distribution/exponential.rb +4 -5
  39. data/lib/distribution/exponential/gsl.rb +13 -9
  40. data/lib/distribution/exponential/ruby.rb +17 -11
  41. data/lib/distribution/f.rb +10 -11
  42. data/lib/distribution/f/gsl.rb +26 -22
  43. data/lib/distribution/f/java.rb +1 -1
  44. data/lib/distribution/f/ruby.rb +104 -105
  45. data/lib/distribution/f/statistics2.rb +22 -19
  46. data/lib/distribution/gamma.rb +5 -7
  47. data/lib/distribution/gamma/gsl.rb +13 -9
  48. data/lib/distribution/gamma/java.rb +1 -1
  49. data/lib/distribution/gamma/ruby.rb +5 -11
  50. data/lib/distribution/hypergeometric.rb +5 -8
  51. data/lib/distribution/hypergeometric/gsl.rb +5 -6
  52. data/lib/distribution/hypergeometric/java.rb +1 -1
  53. data/lib/distribution/hypergeometric/ruby.rb +34 -35
  54. data/lib/distribution/logistic.rb +6 -9
  55. data/lib/distribution/logistic/ruby.rb +14 -9
  56. data/lib/distribution/lognormal.rb +37 -0
  57. data/lib/distribution/lognormal/gsl.rb +21 -0
  58. data/lib/distribution/lognormal/ruby.rb +16 -0
  59. data/lib/distribution/math_extension.rb +187 -231
  60. data/lib/distribution/math_extension/chebyshev_series.rb +281 -272
  61. data/lib/distribution/math_extension/erfc.rb +28 -31
  62. data/lib/distribution/math_extension/exponential_integral.rb +17 -17
  63. data/lib/distribution/math_extension/gammastar.rb +19 -20
  64. data/lib/distribution/math_extension/gsl_utilities.rb +12 -12
  65. data/lib/distribution/math_extension/incomplete_beta.rb +52 -61
  66. data/lib/distribution/math_extension/incomplete_gamma.rb +166 -168
  67. data/lib/distribution/math_extension/log_utilities.rb +20 -22
  68. data/lib/distribution/normal.rb +11 -13
  69. data/lib/distribution/normal/gsl.rb +13 -10
  70. data/lib/distribution/normal/java.rb +30 -1
  71. data/lib/distribution/normal/ruby.rb +69 -59
  72. data/lib/distribution/normal/statistics2.rb +5 -2
  73. data/lib/distribution/normalmultivariate.rb +64 -64
  74. data/lib/distribution/poisson.rb +12 -14
  75. data/lib/distribution/poisson/gsl.rb +7 -7
  76. data/lib/distribution/poisson/java.rb +26 -0
  77. data/lib/distribution/poisson/ruby.rb +38 -9
  78. data/lib/distribution/shorthand.rb +17 -0
  79. data/lib/distribution/t.rb +16 -16
  80. data/lib/distribution/t/gsl.rb +27 -24
  81. data/lib/distribution/t/java.rb +1 -1
  82. data/lib/distribution/t/ruby.rb +99 -100
  83. data/lib/distribution/t/statistics2.rb +19 -19
  84. data/lib/distribution/uniform.rb +26 -0
  85. data/lib/distribution/uniform/gsl.rb +36 -0
  86. data/lib/distribution/uniform/ruby.rb +91 -0
  87. data/lib/distribution/version.rb +3 -0
  88. data/lib/distribution/weibull.rb +10 -0
  89. data/lib/distribution/weibull/gsl.rb +21 -0
  90. data/lib/distribution/weibull/ruby.rb +34 -0
  91. data/spec/beta_spec.rb +48 -50
  92. data/spec/binomial_spec.rb +80 -84
  93. data/spec/bivariatenormal_spec.rb +28 -35
  94. data/spec/chisquare_spec.rb +49 -52
  95. data/spec/distribution_spec.rb +11 -11
  96. data/spec/exponential_spec.rb +48 -39
  97. data/spec/f_spec.rb +73 -71
  98. data/spec/gamma_spec.rb +50 -53
  99. data/spec/hypergeometric_spec.rb +63 -69
  100. data/spec/logistic_spec.rb +31 -37
  101. data/spec/lognormal_spec.rb +54 -0
  102. data/spec/math_extension_spec.rb +192 -209
  103. data/spec/normal_spec.rb +80 -73
  104. data/spec/poisson_spec.rb +78 -36
  105. data/spec/shorthand_spec.rb +19 -22
  106. data/spec/spec_helper.rb +31 -6
  107. data/spec/t_spec.rb +63 -77
  108. data/spec/uniform_spec.rb +154 -0
  109. data/spec/weibull_spec.rb +17 -0
  110. data/vendor/java/commons-math-2.2.jar +0 -0
  111. metadata +91 -111
  112. data.tar.gz.sig +0 -0
  113. data/.autotest +0 -23
  114. data/.gemtest +0 -0
  115. data/Manifest.txt +0 -95
  116. data/README.txt +0 -100
  117. 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
- def rng(k,seed=nil)
6
-
7
- end
8
- def pdf(x,k)
9
- GSL::Ran::chisq_pdf(x.to_f,k.to_i)
10
- end
11
- # Return the P-value of the corresponding integral with
12
- # k degrees of freedom
13
- def p_value(pr,k)
14
- GSL::Cdf::chisq_Pinv(pr.to_f,k.to_i)
15
- end
16
- # Chi-square cumulative distribution function (cdf).
17
- #
18
- # Returns the integral of Chi-squared distribution
19
- # with k degrees of freedom over [0, x]
20
- #
21
- def cdf(x, k)
22
- GSL::Cdf::chisq_P(x.to_f,k.to_i)
23
- end
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
@@ -6,4 +6,4 @@ module Distribution
6
6
  end
7
7
  end
8
8
  end
9
- end
9
+ 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
- w = Distribution::Normal.p_value(1 - y/2) # = p1.0-Distribution::Normal.cdf(y/2)
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
- # v = (1.0 / y - 1.0) / 33.0
30
- # newton_a(y, v) {|x| [q_chi2(n, x), -chi2dens(n, x)] }
31
- -2.0 * Math.log(y)
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
- eps = 1.0e-5
34
- v = 0.0
35
- s = 10.0
36
- loop do
37
- v += s
38
- if s <= eps then break end
39
- if (qe = q_chi2(n, v) - y) == 0.0 then break end
40
- if qe < 0.0
41
- v -= s
42
- s /= 10.0 #/
43
- end
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
- def cdf(x,k)
52
- 1.0-q_chi2(k,x)
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
- chi2 = chi2.to_f
59
- if (df & 1) != 0
60
- chi = Math.sqrt(chi2)
61
- if (df == 1) then return 2 * (1.0-Distribution::Normal.cdf(chi)); end
62
- s = t = chi * Math.exp(-0.5 * chi2) / SQ2PI
63
- k = 3
64
- while k < df
65
- t *= chi2 / k; s += t;
66
- k += 2
67
- end
68
- 2 * (1.0-(Distribution::Normal.cdf(chi)) + s)
69
- else
70
- s = t = Math.exp(-0.5 * chi2)
71
- k = 2
72
- while k < df
73
- t *= chi2 / k; s += t;
74
- k += 2
75
- end
76
- s
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
- # Return the P-value of the corresponding integral with
6
- # k degrees of freedom
7
- def p_value(pr,k)
8
- Statistics2.pchi2X_(k.to_i, pr)
9
- end
10
- # Chi-square cumulative distribution function (cdf).
11
- #
12
- # Returns the integral of Chi-squared distribution
13
- # with k degrees of freedom over [0, x]
14
- #
15
- def cdf(x, k)
16
- Statistics2.chi2dist(k.to_i,x)
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
- def cdf(x,l)
10
- return 0 if x<0
11
- GSL::Cdf.exponential_P(x,1/l.to_f)
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
- def p_value(pr,l)
14
- GSL::Cdf.exponential_Pinv(pr,1/l.to_f)
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
- lambda {p_value(rand(),l)}
7
- end
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
- def cdf(x,l)
13
- return 0 if x<0
14
- 1-Math.exp(-l*x)
9
+
10
+ def pdf(x, l)
11
+ return 0 if x < 0
12
+ l * Math.exp(-l * x)
15
13
  end
16
- def p_value(pr,l)
17
- (-Math.log(1-pr)).quo(l)
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
@@ -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