distribution 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
data.tar.gz.sig CHANGED
Binary file
@@ -1,3 +1,10 @@
1
+ === 0.7.0 / 2011-11-30
2
+
3
+ + Basic log-normal distribution support, with pdf and cdf for ruby [dennyabraham and clbustos]
4
+ * Matthew Peterson add Java support for Poisson and Normal distributions.
5
+ * Updated Logistic, Normal spec. Added LogNormal spec [clbustos]
6
+ * Updated template for new distributions
7
+
1
8
  === 0.6.0 / 2011-09-23
2
9
  * Incomplete Beta functions on math renamed to Regularized beta, because MathExtension::IncompleteBeta calculates regularized beta function, not Incomplete Beta.
3
10
  * Corrected documention on F distribution and added comments on gamma and beta[Claudio Bustos]
@@ -53,6 +53,9 @@ lib/distribution/hypergeometric/java.rb
53
53
  lib/distribution/hypergeometric/ruby.rb
54
54
  lib/distribution/logistic.rb
55
55
  lib/distribution/logistic/ruby.rb
56
+ lib/distribution/lognormal.rb
57
+ lib/distribution/lognormal/gsl.rb
58
+ lib/distribution/lognormal/ruby.rb
56
59
  lib/distribution/math_extension.rb
57
60
  lib/distribution/math_extension/chebyshev_series.rb
58
61
  lib/distribution/math_extension/erfc.rb
@@ -70,6 +73,7 @@ lib/distribution/normal/statistics2.rb
70
73
  lib/distribution/normalmultivariate.rb
71
74
  lib/distribution/poisson.rb
72
75
  lib/distribution/poisson/gsl.rb
76
+ lib/distribution/poisson/java.rb
73
77
  lib/distribution/poisson/ruby.rb
74
78
  lib/distribution/t.rb
75
79
  lib/distribution/t/gsl.rb
@@ -86,6 +90,7 @@ spec/f_spec.rb
86
90
  spec/gamma_spec.rb
87
91
  spec/hypergeometric_spec.rb
88
92
  spec/logistic_spec.rb
93
+ spec/lognormal_spec.rb
89
94
  spec/math_extension_spec.rb
90
95
  spec/normal_spec.rb
91
96
  spec/poisson_spec.rb
@@ -93,3 +98,4 @@ spec/shorthand_spec.rb
93
98
  spec/spec.opts
94
99
  spec/spec_helper.rb
95
100
  spec/t_spec.rb
101
+ vendor/java/commons-math-2.2.jar
data/README.txt CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  == DESCRIPTION:
6
6
 
7
- Statistical Distributions library. Includes Normal univariate and bivariate, T, F, Chi Square, Binomial, Hypergeometric, Exponential, Poisson, Beta and Gamma.
7
+ Statistical Distributions library. Includes Normal univariate and bivariate, T, F, Chi Square, Binomial, Hypergeometric, Exponential, Poisson, Beta, LogNormal and Gamma.
8
8
 
9
9
  Uses Ruby by default and C (statistics2/GSL) or Java extensions where available.
10
10
 
@@ -15,7 +15,6 @@ Includes code from statistics2 on Normal, T, F and Chi Square ruby code [http://
15
15
  * Very fast ruby 1.8.7/1.9.+ implementation, with improved method to calculate factorials and others common functions
16
16
  * All methods tested on several ranges. See spec/
17
17
  * On Jruby and Rubinius, BivariateNormal returns incorrect pdf
18
- * Ruby t distribution's cdf can't calculate fractional df. Install gsl, for now.
19
18
 
20
19
  == API structure
21
20
 
@@ -46,6 +45,7 @@ Shortnames for distributions:
46
45
  * Poisson: pois
47
46
  * Beta: beta
48
47
  * Gamma: gamma
48
+ * LogNormal: lognormal
49
49
 
50
50
  For example
51
51
 
@@ -68,8 +68,8 @@ could be called after including Distribution::Shorthand
68
68
 
69
69
  I try to provide a Ruby version for each method. To increase (notably!) the speed, please install
70
70
 
71
- * Ruby 1.8-1.9: gsl or statistics2
72
- * Java: Apache Math (not yet implemented)
71
+ * Ruby 1.8-1.9: gsl (prefered) or statistics2
72
+ * Java: Not yet implemented
73
73
 
74
74
  == INSTALL:
75
75
 
@@ -41,13 +41,14 @@ describe Distribution::<%= distribution.capitalize %> do
41
41
  it_should_behave_like "<%= distribution %> engine"
42
42
 
43
43
  end
44
-
45
- describe Distribution::<%= distribution.capitalize %>::GSL_ do
46
- before do
47
- @engine=Distribution::<%= distribution.capitalize %>::GSL_
44
+
45
+ if Distribution.has_gsl?
46
+ describe Distribution::<%= distribution.capitalize %>::GSL_ do
47
+ before do
48
+ @engine=Distribution::<%= distribution.capitalize %>::GSL_
49
+ end
50
+ it_should_behave_like "<%= distribution %> engine"
48
51
  end
49
- it_should_behave_like "<%= distribution %> engine"
50
-
51
52
  end
52
53
 
53
54
 
@@ -27,16 +27,16 @@
27
27
  # Specific notices will be placed where there are appropiate
28
28
  #
29
29
  if !respond_to? :define_singleton_method
30
- class Module
31
- public :define_method
32
- end
33
-
34
- class Object
35
- def define_singleton_method(name,&block)
36
- sc=class <<self;self;end
37
- sc.define_method(name,&block)
30
+ class Module
31
+ public :define_method
32
+ end
33
+
34
+ class Object
35
+ def define_singleton_method(name,&block)
36
+ sc=class <<self;self;end
37
+ sc.define_method(name,&block)
38
+ end
38
39
  end
39
- end
40
40
  end
41
41
  require 'distribution/math_extension'
42
42
 
@@ -50,8 +50,7 @@ require 'distribution/math_extension'
50
50
  # Distribution::Normal.p_value(0.95)
51
51
  # => 1.64485364660836
52
52
  module Distribution
53
- VERSION="0.6.0"
54
-
53
+ VERSION="0.7.0"
55
54
  module Shorthand
56
55
  EQUIVALENCES={:p_value=>:p, :cdf=>:cdf, :pdf=>:pdf, :rng=>:r, :exact_pdf=>:epdf, :exact_cdf=>:ecdf, :exact_p_value=>:ep}
57
56
  def self.add_shortcut(sh,m, &block)
@@ -111,7 +110,6 @@ module Distribution
111
110
  # This section was created between a very long reunion
112
111
  # and a 456 Km. travel
113
112
  def create_distribution_methods()
114
-
115
113
  Distribution.libraries_order.each do |l_name|
116
114
  if const_defined? l_name
117
115
  l =const_get(l_name)
@@ -138,19 +136,30 @@ module Distribution
138
136
  end
139
137
 
140
138
  end
139
+ def self.init_java()
140
+ $:.unshift(File.dirname(__FILE__)+"/../vendor/java")
141
+ require 'commons-math-2.2.jar'
142
+ java_import 'org.apache.commons.math.distribution.NormalDistributionImpl'
143
+ java_import 'org.apache.commons.math.distribution.PoissonDistributionImpl'
141
144
 
142
- autoload(:Normal, 'distribution/normal')
143
- autoload(:ChiSquare, 'distribution/chisquare')
144
- autoload(:Gamma, 'distribution/gamma')
145
- autoload(:Beta, 'distribution/beta')
146
- autoload(:T, 'distribution/t')
147
- autoload(:F, 'distribution/f')
148
- autoload(:BivariateNormal, 'distribution/bivariatenormal')
149
- autoload(:Binomial, 'distribution/binomial')
150
- autoload(:Hypergeometric, 'distribution/hypergeometric')
151
- autoload(:Exponential, 'distribution/exponential')
152
- autoload(:Poisson, 'distribution/poisson')
153
- autoload(:Logistic, 'distribution/logistic')
145
+ end
146
+ require 'distribution/normal'
147
+ require 'distribution/chisquare'
148
+ require 'distribution/gamma'
149
+ require 'distribution/beta'
150
+ require 'distribution/t'
151
+ require 'distribution/f'
152
+ require 'distribution/bivariatenormal'
153
+ require 'distribution/binomial'
154
+ require 'distribution/hypergeometric'
155
+ require 'distribution/exponential'
156
+ require 'distribution/poisson'
157
+ require 'distribution/logistic'
158
+ require 'distribution/lognormal'
159
+
160
+ if has_java?
161
+ init_java()
162
+ end
154
163
  end
155
164
 
156
165
 
@@ -23,7 +23,7 @@ module Distribution
23
23
  # * s: variance related parameter
24
24
 
25
25
  ##
26
- # :singleton-method: cdf(x , u,s)
26
+ # :singleton-method: cdf(x,u,s)
27
27
  # Returns the cdf for logistic distribution (F(x,u,s))
28
28
  # * u: mean
29
29
  # * s: variance related parameter
@@ -2,14 +2,14 @@ module Distribution
2
2
  module Logistic
3
3
  module Ruby_
4
4
  class << self
5
- def rng(u,s)
6
- lambda {p_value(rand(),u,s)}
7
- end
5
+ def rng(u,s)
6
+ lambda {p_value(rand(),u,s)}
7
+ end
8
8
  def pdf(x,u,s )
9
- (Math.exp(-(x-u)/s))/(s*(1+Math.exp(-(x-u)/s)**2))
9
+ (Math.exp(-(x-u) / s)) / (s*(1+Math.exp(-(x-u) / s)**2))
10
10
  end
11
11
  def cdf(x,u,s )
12
- 1/(1+Math.exp(-(x-u)/s))
12
+ 1/(1+Math.exp(-(x-u) / s))
13
13
  end
14
14
  def p_value(pr,u,s )
15
15
  u+s*Math.log(pr/(1-pr))
@@ -0,0 +1,39 @@
1
+ require 'distribution/lognormal/gsl'
2
+ require 'distribution/lognormal/ruby'
3
+
4
+ module Distribution
5
+ # From Wikipedia:
6
+ # In probability theory, a log-normal distribution is a probability
7
+ # distribution of a random variable whose logarithm is normally
8
+ # distributed. If X is a random variable with a normal distribution, then
9
+ # Y = exp(X) has a log-normal distribution; likewise, if Y is
10
+ # log-normally distributed, then X = log(Y) is normally distributed. (This
11
+ # is true regardless of the base of the logarithmic function: if loga(Y) is
12
+ # normally distributed, then so is logb(Y), for any two positive numbers
13
+ # a, b ≠ 1.)
14
+ #
15
+ # This module calculate the pdf, cdf and inverse cdf for Beta Distribution.
16
+ #
17
+ module LogNormal
18
+ extend Distributable
19
+ SHORTHAND='lognormal'
20
+ create_distribution_methods
21
+
22
+ ##
23
+ # :singleton-method: pdf(x,u,s)
24
+ # Returns PDF of of Lognormal distribution with parameters u (position) and
25
+ # s (deviation)
26
+
27
+
28
+ ##
29
+ # :singleton-method: cdf(x,u,s)
30
+ # Returns the CDF of Lognormal distribution of x with parameters
31
+ # u (position) and s(deviation)
32
+
33
+ ##
34
+ # :singleton-method: p_value(pr,u,s)
35
+ # Return the quantile of the corresponding integral +pr+
36
+ # on a lognormal distribution's cdf with parameters z and s
37
+
38
+ end
39
+ end
@@ -0,0 +1,19 @@
1
+ module Distribution
2
+ module LogNormal
3
+ module GSL_
4
+ class << self
5
+ def pdf(x,u,s)
6
+ GSL::Ran::lognormal_pdf(x.to_f, u.to_f, s.to_f)
7
+ end
8
+
9
+ def p_value(pr,u,s)
10
+ GSL::Cdf::lognormal_Pinv(pr.to_f, u.to_f, s.to_f)
11
+ end
12
+
13
+ def cdf(x,u,s)
14
+ GSL::Cdf::lognormal_P(x.to_f, u.to_f, s.to_f)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ module Distribution
2
+ module LogNormal
3
+ module Ruby_
4
+ class << self
5
+
6
+ def pdf(x,u,s)
7
+ raise "x should be > 0 " if x < 0
8
+ (1.0/(x*s*Math.sqrt(2*Math::PI)))*Math.exp(-((Math.log(x)-u)**2 / (2*s**2)))
9
+ end
10
+
11
+ #def p_value(pr,u,s)
12
+ #end
13
+
14
+ def cdf(x,u,s)
15
+ Distribution::Normal.cdf((Math.log(x)-u) / s)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -68,10 +68,13 @@ module Distribution
68
68
  # From statistics2
69
69
  def gamma(x)
70
70
  if (x < 0.0)
71
- return Math::PI / (Math.sin(Math.PI * x) * Math.exp(loggamma(1 - x))) #/
71
+ return Math::PI / (Math.sin(Math::PI * x) * Math.exp(loggamma(1 - x))) #/
72
72
  end
73
73
  Math.exp(loggamma(x))
74
74
  end
75
+ def lgamma(x)
76
+ [loggamma(x.abs), Math.gamma(x) < 0 ? -1 : 1]
77
+ end
75
78
  end
76
79
  # Useful additions to Math
77
80
  module MathExtension
@@ -281,7 +284,7 @@ module Distribution
281
284
  end
282
285
 
283
286
  # Not the same as erfc. This is the GSL version, which may have slightly different results.
284
- def erfc_e x, with_error = false
287
+ def erfc_e(x, with_error = false)
285
288
  Erfc.evaluate(x, with_error)
286
289
  end
287
290
 
@@ -365,7 +368,7 @@ if RUBY_VERSION<"1.9"
365
368
  module Math
366
369
  remove_method :loggamma
367
370
  include Distribution::MathExtension18
368
- module_function :gamma, :loggamma
371
+ module_function :gamma, :loggamma, :lgamma
369
372
  end
370
373
  end
371
374
 
@@ -23,7 +23,7 @@ module Distribution
23
23
  class << self
24
24
  # Estimates erfc(x) valid for 8 < x < 100
25
25
  # erfc8_sum from GSL-1.9
26
- def erfc8_sum x
26
+ def erfc8_sum(x)
27
27
  num = P[5]
28
28
  4.downto(0) { |i| num = x*num + P[i] }
29
29
  den = Q[6]
@@ -31,7 +31,7 @@ module Distribution
31
31
  num / den
32
32
  end
33
33
 
34
- def erfc8 x
34
+ def erfc8(x)
35
35
  erfc8_sum(x) * Math.exp(-x*x)
36
36
  end
37
37
 
@@ -54,7 +54,7 @@ module Distribution
54
54
  e *= ex2
55
55
  end
56
56
  elsif ax < 10.0
57
- exterm = Math.exp(-x*x)/ax
57
+ exterm = Math.exp(-x*x) / ax
58
58
  t = (2*ax-15).quo(5)
59
59
  e = ChebyshevSeries.evaluate(:erfc_x510, t, with_error)
60
60
  if with_error
@@ -3,6 +3,34 @@ module Distribution
3
3
  # TODO
4
4
  module Java_
5
5
  class << self
6
+ #==
7
+ # Generate random variables from the provided distribution
8
+ def rng(mean=0,sigma=1,seed=nil)
9
+ dist = NormalDistributionImpl.new(mean, sigma)
10
+ lambda { dist.sample }
11
+ end
12
+
13
+ #==
14
+ # Get the inverse cumulative density function (p-value) for qn
15
+ def p_value(qn)
16
+ dist = NormalDistributionImpl.new
17
+ dist.inverseCumulativeProbability(qn)
18
+ end
19
+
20
+ #==
21
+ # Return the cumulative density function at x
22
+ def cdf(x)
23
+ dist = NormalDistributionImpl.new
24
+ dist.cumulativeProbability(x)
25
+ end
26
+
27
+ #==
28
+ # Return the probability density function at x
29
+ def pdf(x)
30
+ dist = NormalDistributionImpl.new
31
+ dist.density(x)
32
+ end
33
+
6
34
  end
7
35
  end
8
36
  end
@@ -1,6 +1,6 @@
1
1
  require 'distribution/poisson/ruby'
2
2
  require 'distribution/poisson/gsl'
3
- #require 'distribution/poisson/java'
3
+ require 'distribution/poisson/java'
4
4
 
5
5
 
6
6
  module Distribution
@@ -0,0 +1,31 @@
1
+ module Distribution
2
+ module Poisson
3
+ module Java_
4
+ class << self
5
+ #==
6
+ # Create the PoissonDistributionImpl object for use in calculations
7
+ # with mean of l
8
+ def create_distribution(l)
9
+ PoissonDistributionImpl.new(l)
10
+ end
11
+
12
+ #==
13
+ #
14
+ def pdf(k,l)
15
+ dist = create_distribution(l)
16
+ dist.probability(k)
17
+ end
18
+
19
+ def cdf(k,l)
20
+ dist = create_distribution(l)
21
+ dist.cumulativeProbability(k)
22
+ end
23
+
24
+ # def p_value(pr,l)
25
+ # dist = create_distribution(l)
26
+ # dist.inverseCumulativeProbability(pr)
27
+ # end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,6 +1,8 @@
1
1
  require 'distribution/t/ruby'
2
2
  require 'distribution/t/gsl'
3
- require 'distribution/t/statistics2'
3
+ # Removed statistics2 support for t, because
4
+ # can't calculate correctly cdf for rational d.f
5
+ # require 'distribution/t/statistics2'
4
6
  require 'distribution/t/java'
5
7
 
6
8
  module Distribution
@@ -19,18 +19,18 @@ describe Distribution::Beta do
19
19
  it_only_with_gsl "should return correct cdf" do
20
20
  if @engine.respond_to? :cdf
21
21
  # From GSL-1.9.
22
- TOL = 1048576.0*Float::EPSILON
22
+ tol = 1048576.0*Float::EPSILON
23
23
  @engine.cdf(0.0, 1.2, 1.3).should eq(0.0)
24
- @engine.cdf(1e-100, 1.2, 1.3).should be_within(TOL).of(1.34434944656489596e-120)
25
- @engine.cdf(0.001, 1.2, 1.3).should be_within(TOL).of(3.37630042504535813e-4)
26
- @engine.cdf(0.01, 1.2, 1.3).should be_within(TOL).of(5.34317264038929473e-3)
27
- @engine.cdf(0.1, 1.2, 1.3).should be_within(TOL).of(8.33997828306748346e-2)
28
- @engine.cdf(0.325, 1.2, 1.3).should be_within(TOL).of(3.28698654180583916e-1)
29
- @engine.cdf(0.5, 1.2, 1.3).should be_within(TOL).of(5.29781429451299081e-1)
30
- @engine.cdf(0.9, 1.2, 1.3).should be_within(TOL).of(9.38529397224430659e-1)
31
- @engine.cdf(0.99, 1.2, 1.3).should be_within(TOL).of(9.96886438341254380e-1)
32
- @engine.cdf(0.999, 1.2, 1.3).should be_within(TOL).of(9.99843792833067634e-1)
33
- @engine.cdf(1.0, 1.2, 1.3).should be_within(TOL).of(1.0)
24
+ @engine.cdf(1e-100, 1.2, 1.3).should be_within(tol).of(1.34434944656489596e-120)
25
+ @engine.cdf(0.001, 1.2, 1.3).should be_within(tol).of(3.37630042504535813e-4)
26
+ @engine.cdf(0.01, 1.2, 1.3).should be_within(tol).of(5.34317264038929473e-3)
27
+ @engine.cdf(0.1, 1.2, 1.3).should be_within(tol).of(8.33997828306748346e-2)
28
+ @engine.cdf(0.325, 1.2, 1.3).should be_within(tol).of(3.28698654180583916e-1)
29
+ @engine.cdf(0.5, 1.2, 1.3).should be_within(tol).of(5.29781429451299081e-1)
30
+ @engine.cdf(0.9, 1.2, 1.3).should be_within(tol).of(9.38529397224430659e-1)
31
+ @engine.cdf(0.99, 1.2, 1.3).should be_within(tol).of(9.96886438341254380e-1)
32
+ @engine.cdf(0.999, 1.2, 1.3).should be_within(tol).of(9.99843792833067634e-1)
33
+ @engine.cdf(1.0, 1.2, 1.3).should be_within(tol).of(1.0)
34
34
  else
35
35
  pending("No #{@engine}.cdf")
36
36
  end
@@ -19,21 +19,21 @@ shared_examples_for "Gamma engine" do
19
19
  it_only_with_gsl "should return correct cdf" do
20
20
  if @engine.respond_to? :cdf
21
21
  # From GSL-1.9.
22
- TOL = 1048576.0*Float::EPSILON
22
+ tol = 1048576.0*Float::EPSILON
23
23
  @engine.cdf(0.0, 1.0, 1.0).should eq(0.0)
24
- @engine.cdf(1e-100, 1.0, 1.0).should be_within(TOL).of(1e-100)
25
- @engine.cdf(0.001, 1.0, 1.0).should be_within(TOL).of(9.99500166625008332e-4)
26
- @engine.cdf(0.01, 1.0, 1.0).should be_within(TOL).of(9.95016625083194643e-3)
27
- @engine.cdf(0.1, 1.0, 1.0).should be_within(TOL).of(9.51625819640404268e-2)
28
- @engine.cdf(0.325, 1.0, 1.0).should be_within(TOL).of(2.77472646357927811e-1)
29
- @engine.cdf(1.0, 1.0, 1.0).should be_within(TOL).of(6.32120558828557678e-1)
30
- @engine.cdf(1.5, 1.0, 1.0).should be_within(TOL).of(7.76869839851570171e-1)
31
- @engine.cdf(2.0, 1.0, 1.0).should be_within(TOL).of(8.64664716763387308e-1)
32
- @engine.cdf(10.0, 1.0, 1.0).should be_within(TOL).of(9.99954600070237515e-1)
33
- @engine.cdf(20.0, 1.0, 1.0).should be_within(TOL).of(9.99999997938846378e-1)
34
- @engine.cdf(100.0, 1.0, 1.0).should be_within(TOL).of(1e0)
35
- @engine.cdf(1000.0, 1.0, 1.0).should be_within(TOL).of(1e0)
36
- @engine.cdf(10000.0, 1.0, 1.0).should be_within(TOL).of(1e0)
24
+ @engine.cdf(1e-100, 1.0, 1.0).should be_within(tol).of(1e-100)
25
+ @engine.cdf(0.001, 1.0, 1.0).should be_within(tol).of(9.99500166625008332e-4)
26
+ @engine.cdf(0.01, 1.0, 1.0).should be_within(tol).of(9.95016625083194643e-3)
27
+ @engine.cdf(0.1, 1.0, 1.0).should be_within(tol).of(9.51625819640404268e-2)
28
+ @engine.cdf(0.325, 1.0, 1.0).should be_within(tol).of(2.77472646357927811e-1)
29
+ @engine.cdf(1.0, 1.0, 1.0).should be_within(tol).of(6.32120558828557678e-1)
30
+ @engine.cdf(1.5, 1.0, 1.0).should be_within(tol).of(7.76869839851570171e-1)
31
+ @engine.cdf(2.0, 1.0, 1.0).should be_within(tol).of(8.64664716763387308e-1)
32
+ @engine.cdf(10.0, 1.0, 1.0).should be_within(tol).of(9.99954600070237515e-1)
33
+ @engine.cdf(20.0, 1.0, 1.0).should be_within(tol).of(9.99999997938846378e-1)
34
+ @engine.cdf(100.0, 1.0, 1.0).should be_within(tol).of(1e0)
35
+ @engine.cdf(1000.0, 1.0, 1.0).should be_within(tol).of(1e0)
36
+ @engine.cdf(10000.0, 1.0, 1.0).should be_within(tol).of(1e0)
37
37
  else
38
38
  pending("No #{@engine}.cdf")
39
39
  end
@@ -6,7 +6,7 @@ describe Distribution::Logistic do
6
6
  it "should return correct pdf" do
7
7
  if @engine.respond_to? :pdf
8
8
  1.upto(10) {
9
- u=rand()
9
+ u=rand()
10
10
  s=rand()+1
11
11
  x=rand()*100-50
12
12
  exp=Math.exp(-(x-u) / s) / (s*(1+Math.exp(-(x-u) / s)**2))
@@ -19,14 +19,13 @@ describe Distribution::Logistic do
19
19
 
20
20
  it "should return correct cdf" do
21
21
  if @engine.respond_to? :cdf
22
-
23
-
24
22
  1.upto(100) {
25
- u=rand()
26
- s=rand()+1
27
- x=rand()*100-50
28
- exp=1/(1+Math.exp(-(x-u)/s))
29
- @engine.cdf(x,u,s).should eq(exp)
23
+ u=rand()
24
+ s=rand()*100
25
+ x=rand()*100-50
26
+ exp=1/(1+Math.exp(-(x-u) / s))
27
+
28
+ @engine.cdf(x,u,s).should eq(exp)
30
29
  }
31
30
 
32
31
  else
@@ -38,11 +37,11 @@ describe Distribution::Logistic do
38
37
  it "should return correct p_value" do
39
38
  if @engine.respond_to? :p_value
40
39
  1.upto(9) {|i|
41
- u=rand()
42
- s=rand()+1
43
- x=@engine.p_value(i/10,u,s)
44
- @engine.cdf(x,u,s).should eq i/10
45
- }
40
+ u=rand()
41
+ s=rand()*100
42
+ x=@engine.p_value(i/10.0,u,s)
43
+ @engine.cdf(x,u,s).should be_within(1e-10).of(i/10.0)
44
+ }
46
45
  else
47
46
  pending("No #{@engine}.cdf")
48
47
  end
@@ -0,0 +1,60 @@
1
+ require File.expand_path(File.dirname(__FILE__)+"/spec_helper.rb")
2
+
3
+ describe Distribution::LogNormal do
4
+
5
+ shared_examples_for "log-normal engine" do
6
+ it "should return correct pdf" do
7
+ if @engine.respond_to? :pdf
8
+ 1.upto(10) {
9
+ u=rand()
10
+ s=rand()*100
11
+ x=rand()*50
12
+ exp=(1.0/(x*s*Math.sqrt(2*Math::PI)))*Math.exp(-((Math.log(x)-u)**2 / (2*s**2)))
13
+ @engine.pdf(x,u,s).should be_within(1e-10).of(exp)
14
+ }
15
+ else
16
+ pending("No #{@engine}.pdf")
17
+ end
18
+ end
19
+ it "should return correct cdf" do
20
+ if @engine.respond_to? :cdf
21
+ 1.upto(10) {
22
+ u=rand()
23
+ s=rand()*100
24
+ x=rand()*50
25
+ exp=Distribution::Normal.cdf((Math.log(x) - u) / s)
26
+ @engine.cdf(x,u,s).should be_within(1e-10).of(exp)
27
+ }
28
+ else
29
+ pending("No #{@engine}.cdf")
30
+ end
31
+ end
32
+
33
+ end
34
+
35
+ describe "singleton" do
36
+ before do
37
+ @engine=Distribution::LogNormal
38
+ end
39
+ it_should_behave_like "log-normal engine"
40
+ end
41
+
42
+ describe Distribution::LogNormal::Ruby_ do
43
+ before do
44
+ @engine=Distribution::LogNormal::Ruby_
45
+ end
46
+ it_should_behave_like "log-normal engine"
47
+
48
+ end
49
+ if Distribution.has_gsl?
50
+ describe Distribution::LogNormal::GSL_ do
51
+ before do
52
+ @engine=Distribution::LogNormal::GSL_
53
+ end
54
+ it_should_behave_like "log-normal engine"
55
+ end
56
+ end
57
+
58
+
59
+
60
+ end
@@ -119,16 +119,18 @@ describe Distribution::MathExtension do
119
119
 
120
120
 
121
121
  it "unnormalized_incomplete_gamma with x=0 should return correct values" do
122
- Math.unnormalized_incomplete_gamma(-1.5, 0).should be_within(1e-10).of(4.0*Math.sqrt(Math::PI)/3.0)
122
+ Math.unnormalized_incomplete_gamma(-1.5, 0).should be_within(1e-10).of(4.0*Math.sqrt(Math::PI) / 3.0)
123
123
  Math.unnormalized_incomplete_gamma(-0.5, 0).should be_within(1e-10).of(-2*Math.sqrt(Math::PI))
124
124
  Math.unnormalized_incomplete_gamma(0.5, 0).should be_within(1e-10).of(Math.sqrt(Math::PI))
125
125
  Math.unnormalized_incomplete_gamma(1.0, 0).should eq 1.0
126
- Math.unnormalized_incomplete_gamma(1.5, 0).should be_within(1e-10).of(Math.sqrt(Math::PI)/2.0)
126
+ Math.unnormalized_incomplete_gamma(1.5, 0).should be_within(1e-10).of(Math.sqrt(Math::PI) / 2.0)
127
127
  Math.unnormalized_incomplete_gamma(2.0, 0).should eq 1.0
128
128
  Math.unnormalized_incomplete_gamma(2.5, 0).should be_within(1e-10).of(0.75*Math.sqrt(Math::PI))
129
- Math.unnormalized_incomplete_gamma(3.0, 0).should eq 2.0
129
+
130
+ Math.unnormalized_incomplete_gamma(3.0, 0).should be_within(1e-12).of(2.0)
131
+
130
132
  Math.unnormalized_incomplete_gamma(3.5, 0).should be_within(1e-10).of(15.0*Math.sqrt(Math::PI) / 8.0)
131
- Math.unnormalized_incomplete_gamma(4.0, 0).should eq 6.0
133
+ Math.unnormalized_incomplete_gamma(4.0, 0).should be_within(1e-12).of(6.0)
132
134
  end
133
135
 
134
136
  it "incomplete_gamma should return correct values" do
@@ -7,7 +7,7 @@ describe Distribution::Poisson do
7
7
  if @engine.respond_to? :pdf
8
8
  [0.5,1,1.5].each {|l|
9
9
  1.upto(5) {|k|
10
- @engine.pdf(k,l).should be_within(1e-10).of((l**k*Math.exp(-l)).quo(Math.factorial(k)))
10
+ @engine.pdf(k,l).should be_within(1e-10).of( (l**k*Math.exp(-l)).quo(Math.factorial(k)) )
11
11
  }
12
12
  }
13
13
  else
@@ -27,6 +27,8 @@ describe Distribution::Poisson do
27
27
  pending("No #{@engine}.cdf")
28
28
  end
29
29
  end
30
+
31
+
30
32
 
31
33
 
32
34
  it "should return correct p_value" do
@@ -59,14 +61,32 @@ describe Distribution::Poisson do
59
61
  it_should_behave_like "poisson engine"
60
62
 
61
63
  end
62
-
63
- describe Distribution::Poisson::GSL_ do
64
- before do
65
- @engine=Distribution::Poisson::GSL_
64
+ if Distribution.has_gsl?
65
+ describe Distribution::Poisson::GSL_ do
66
+ before do
67
+ @engine=Distribution::Poisson::GSL_
68
+ end
69
+ it_should_behave_like "poisson engine"
70
+
71
+ end
72
+ end
73
+ if Distribution.has_java?
74
+ describe Distribution::Poisson::Java_ do
75
+ before do
76
+ @engine=Distribution::Poisson::Java_
77
+ end
78
+ it_should_behave_like "poisson engine"
79
+
80
+
81
+ it "should return correct cdf" do
82
+ [0.5,1,1.5,4,10].each {|l|
83
+ 1.upto(5) {|k|
84
+ @engine.cdf(k,l).should be_within(1e-10).of(Distribution::Poisson::Ruby_.cdf(k,l))
85
+ }
86
+ }
87
+ end
88
+
89
+
66
90
  end
67
- it_should_behave_like "poisson engine"
68
-
69
91
  end
70
-
71
-
72
92
  end
@@ -20,4 +20,15 @@ module ExampleWithGSL
20
20
  end
21
21
  end
22
22
  end
23
+
24
+ def it_only_with_java(name,&block)
25
+ it(name) do
26
+ if Distribution.has_java?
27
+ instance_eval(&block)
28
+ else
29
+ pending("Requires Java")
30
+ end
31
+ end
32
+ end
33
+
23
34
  end
metadata CHANGED
@@ -1,8 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: distribution
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.6.0
4
+ hash: 3
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 7
9
+ - 0
10
+ version: 0.7.0
6
11
  platform: ruby
7
12
  authors:
8
13
  - Claudio Bustos
@@ -31,7 +36,7 @@ cert_chain:
31
36
  rpP0jjs0
32
37
  -----END CERTIFICATE-----
33
38
 
34
- date: 2011-08-23 00:00:00 -03:00
39
+ date: 2011-11-30 00:00:00 -03:00
35
40
  default_executable:
36
41
  dependencies:
37
42
  - !ruby/object:Gem::Dependency
@@ -42,6 +47,11 @@ dependencies:
42
47
  requirements:
43
48
  - - ">="
44
49
  - !ruby/object:Gem::Version
50
+ hash: 7
51
+ segments:
52
+ - 2
53
+ - 0
54
+ - 4
45
55
  version: 2.0.4
46
56
  type: :development
47
57
  version_requirements: *id001
@@ -53,6 +63,10 @@ dependencies:
53
63
  requirements:
54
64
  - - ">="
55
65
  - !ruby/object:Gem::Version
66
+ hash: 3
67
+ segments:
68
+ - 2
69
+ - 0
56
70
  version: "2.0"
57
71
  type: :development
58
72
  version_requirements: *id002
@@ -64,6 +78,9 @@ dependencies:
64
78
  requirements:
65
79
  - - ">="
66
80
  - !ruby/object:Gem::Version
81
+ hash: 3
82
+ segments:
83
+ - 0
67
84
  version: "0"
68
85
  type: :development
69
86
  version_requirements: *id003
@@ -73,13 +90,18 @@ dependencies:
73
90
  requirement: &id004 !ruby/object:Gem::Requirement
74
91
  none: false
75
92
  requirements:
76
- - - ~>
93
+ - - ">="
77
94
  - !ruby/object:Gem::Version
78
- version: "2.12"
95
+ hash: 47
96
+ segments:
97
+ - 2
98
+ - 8
99
+ - 0
100
+ version: 2.8.0
79
101
  type: :development
80
102
  version_requirements: *id004
81
103
  description: |-
82
- Statistical Distributions library. Includes Normal univariate and bivariate, T, F, Chi Square, Binomial, Hypergeometric, Exponential, Poisson, Beta and Gamma.
104
+ Statistical Distributions library. Includes Normal univariate and bivariate, T, F, Chi Square, Binomial, Hypergeometric, Exponential, Poisson, Beta, LogNormal and Gamma.
83
105
 
84
106
  Uses Ruby by default and C (statistics2/GSL) or Java extensions where available.
85
107
 
@@ -150,6 +172,9 @@ files:
150
172
  - lib/distribution/hypergeometric/ruby.rb
151
173
  - lib/distribution/logistic.rb
152
174
  - lib/distribution/logistic/ruby.rb
175
+ - lib/distribution/lognormal.rb
176
+ - lib/distribution/lognormal/gsl.rb
177
+ - lib/distribution/lognormal/ruby.rb
153
178
  - lib/distribution/math_extension.rb
154
179
  - lib/distribution/math_extension/chebyshev_series.rb
155
180
  - lib/distribution/math_extension/erfc.rb
@@ -167,6 +192,7 @@ files:
167
192
  - lib/distribution/normalmultivariate.rb
168
193
  - lib/distribution/poisson.rb
169
194
  - lib/distribution/poisson/gsl.rb
195
+ - lib/distribution/poisson/java.rb
170
196
  - lib/distribution/poisson/ruby.rb
171
197
  - lib/distribution/t.rb
172
198
  - lib/distribution/t/gsl.rb
@@ -183,6 +209,7 @@ files:
183
209
  - spec/gamma_spec.rb
184
210
  - spec/hypergeometric_spec.rb
185
211
  - spec/logistic_spec.rb
212
+ - spec/lognormal_spec.rb
186
213
  - spec/math_extension_spec.rb
187
214
  - spec/normal_spec.rb
188
215
  - spec/poisson_spec.rb
@@ -190,7 +217,7 @@ files:
190
217
  - spec/spec.opts
191
218
  - spec/spec_helper.rb
192
219
  - spec/t_spec.rb
193
- - .gemtest
220
+ - vendor/java/commons-math-2.2.jar
194
221
  has_rdoc: true
195
222
  homepage: https://github.com/clbustos/distribution
196
223
  licenses: []
@@ -206,17 +233,23 @@ required_ruby_version: !ruby/object:Gem::Requirement
206
233
  requirements:
207
234
  - - ">="
208
235
  - !ruby/object:Gem::Version
236
+ hash: 3
237
+ segments:
238
+ - 0
209
239
  version: "0"
210
240
  required_rubygems_version: !ruby/object:Gem::Requirement
211
241
  none: false
212
242
  requirements:
213
243
  - - ">="
214
244
  - !ruby/object:Gem::Version
245
+ hash: 3
246
+ segments:
247
+ - 0
215
248
  version: "0"
216
249
  requirements: []
217
250
 
218
251
  rubyforge_project: distribution
219
- rubygems_version: 1.6.0
252
+ rubygems_version: 1.3.7
220
253
  signing_key:
221
254
  specification_version: 3
222
255
  summary: Statistical Distributions library
metadata.gz.sig CHANGED
Binary file
data/.gemtest DELETED
File without changes