distribution 0.6.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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