croupier 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -34,6 +34,8 @@ where:
34
34
 
35
35
  Current version implements the following distributions:
36
36
 
37
+ * Bernoulli
38
+ * Binomial
37
39
  * Cauchy
38
40
  * Exponential
39
41
  * Geometric
@@ -65,6 +67,18 @@ And then use the the distribution you want to generate the sample. You can get j
65
67
  dist.generate_sample(100) #=> returns an array of 100 random numbers following an exponential with rate 1.7
66
68
  dist.generate_number #=> returns one random number following an exponential with rate 1.7
67
69
 
70
+ It's posible to instantiate each Distribution class directly:
71
+
72
+ dist = Croupier::Distributions::Exponential.new(:lambda => 1.7)
73
+
74
+ or calling Distributions methods:
75
+
76
+ dist = Croupier::Distributions.exponential :lambda => 1.7
77
+
78
+ To get a list of all available distributions/methods in Distributions module call ```list```
79
+
80
+ Croupier::Distributions.list
81
+
68
82
  ## How to generate a distribution.
69
83
 
70
84
  There are several ways. The easiest one is to override ```generate_number``` or ```generate_sample``` (one is enough).
data/lib/croupier.rb CHANGED
@@ -1,6 +1,8 @@
1
+ require 'croupier/version'
1
2
  require 'croupier/cli/trollop'
2
3
  require 'croupier/exceptions'
3
4
  require 'croupier/distribution'
5
+ require 'croupier/distributions'
4
6
  Dir[File.join(File.dirname(__FILE__), "./croupier/distributions/*.rb")].each {|f| require f}
5
7
  require 'croupier/cli/application'
6
8
  #####################################################################
@@ -13,13 +13,10 @@ module Croupier
13
13
  # It Checks and loads the available distributions.
14
14
  def initialize
15
15
  @distribution_list, @distributions_options = {}, {}
16
- ::Croupier::Distributions.constants.each{|distrib|
17
- d = ::Croupier::Distributions.const_get(distrib)
18
- if d.is_a?(Class) && d.superclass == Croupier::Distribution
19
- @distribution_list[d.cli_name] = d
20
- @distributions_options[d.cli_name] = d.cli_options
21
- end
22
- }
16
+ ::Croupier::Distributions.all.each do |d|
17
+ @distribution_list[d.cli_name] = d
18
+ @distributions_options[d.cli_name] = d.cli_options
19
+ end
23
20
  end
24
21
 
25
22
  # Run the Croupier application. The run method performs the following steps:
@@ -39,6 +36,7 @@ module Croupier
39
36
  #Trollop needs this vars locally
40
37
  available_distribution_list = @distribution_list.keys
41
38
  available_distributions_options = @distributions_options
39
+ version = ::Croupier::VERSION
42
40
 
43
41
  opts = Trollop::options do
44
42
  banner <<-EOS
@@ -54,6 +52,7 @@ Usage:
54
52
  Get options list for any distribution with: croupier <distrib> --help
55
53
 
56
54
  EOS
55
+ version "Croupier version #{version}"
57
56
  stop_on available_distribution_list
58
57
  end
59
58
 
@@ -70,6 +70,4 @@ module Croupier
70
70
  end
71
71
  end
72
72
 
73
- module Distributions
74
- end
75
73
  end
@@ -0,0 +1,29 @@
1
+ module Croupier
2
+
3
+ module Distributions
4
+ class << self
5
+ # An array containing all available Distribution classes
6
+ def all
7
+ ::Croupier::Distributions.constants(false).inject([]){|list, distrib|
8
+ d = ::Croupier::Distributions.const_get(distrib)
9
+ (d.is_a?(Class) && d.superclass == Croupier::Distribution) ? list << d : list
10
+ }.uniq.compact
11
+ end
12
+
13
+ # list of all available distribution names (and methods on Distributions module)
14
+ def list
15
+ self.all.map(&:cli_name).sort
16
+ end
17
+
18
+ def method_missing(method, *args, &block) # :nodoc:
19
+ return super unless self.respond_to?(method)
20
+ self.all.select{|d| d.cli_name == method.to_s}.first.new *args
21
+ end
22
+
23
+ def respond_to?(method, include_private = false) # :nodoc:
24
+ self.list.include?(method.to_s) || super(method, include_private)
25
+ end
26
+ end
27
+ end
28
+
29
+ end
@@ -0,0 +1,44 @@
1
+ module Croupier
2
+ module Distributions
3
+
4
+ #####################################################################
5
+ # Bernoulli Distribution
6
+ # Discrete probability distribution taking value 1 with success
7
+ # probability p and value 0 with failure probability 1-p
8
+ # Equivalent to a Binomial(1,p)
9
+ class Bernoulli < ::Croupier::Distribution
10
+
11
+ def initialize(options={})
12
+ @name = "Bernoulli distribution"
13
+ @description = "Discrete probability distribution taking value 1 with success probability p and value 0 with failure probability 1-p."
14
+ configure(options)
15
+ raise Croupier::InputParamsError, "Probability of success must be in the interval [0,1]" if params[:success] > 1 || params[:success] < 0
16
+ end
17
+
18
+ def generate_number
19
+ binomial_1_p.generate_number
20
+ end
21
+
22
+ def default_parameters
23
+ {:success => 0.5}
24
+ end
25
+
26
+ def self.cli_name
27
+ "bernoulli"
28
+ end
29
+
30
+ def self.cli_options
31
+ {:options => [
32
+ [:success, 'success probability', {:type=>:float, :short => "-p", :default => 0.5}]
33
+ ],
34
+ :banner => "Bernoulli distribution. Discrete probability distribution taking value 1 with success probability p and value 0 with failure probability 1-p."
35
+ }
36
+ end
37
+
38
+ private
39
+ def binomial_1_p
40
+ @binomial_1_p ||= ::Croupier::Distributions::Binomial.new(:success => params[:success], :size => 1)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,53 @@
1
+ module Croupier
2
+ module Distributions
3
+
4
+ #####################################################################
5
+ # Binomial Distribution
6
+ # Discrete probability distribution of the number of successes in a
7
+ # sequence of Bernoulli trials each of which yields success with
8
+ # probability p
9
+ class Binomial < ::Croupier::Distribution
10
+
11
+ def initialize(options={})
12
+ @name = "Binomial distribution"
13
+ @description = "Discrete probability distribution of the number of successes in a sequence of Bernoulli trials."
14
+ configure(options)
15
+ raise Croupier::InputParamsError, "Probability of success must be in the interval [0,1]" if params[:success] > 1 || params[:success] < 0
16
+ end
17
+
18
+ def generate_number
19
+ x = -1
20
+ s = 0
21
+ loop do
22
+ s += base_geometric.generate_number
23
+ x += 1
24
+ break if s > params[:size]
25
+ end
26
+ x
27
+ end
28
+
29
+ def default_parameters
30
+ {:success => 0.5, :size => 1}
31
+ end
32
+
33
+ def self.cli_name
34
+ "binomial"
35
+ end
36
+
37
+ def self.cli_options
38
+ {:options => [
39
+ [:size, 'number of trials', {:type => :integer, :default => 1}],
40
+ [:success, 'success probability of each trial', {:type=>:float, :short => "-p", :default => 0.5}]
41
+ ],
42
+ :banner => "Binomial distribution. Discrete probability distribution of the number of successes in a sequence of Bernoulli trials."
43
+ }
44
+ end
45
+
46
+ private
47
+ def base_geometric
48
+ @base_geometric ||= ::Croupier::Distributions::Geometric.new(success: params[:success])
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -14,7 +14,7 @@ module Croupier
14
14
 
15
15
  def initialize(options={})
16
16
  @name = "Geometric distribution"
17
- @description = "Discrete probability distribution that expresses the the number of X Bernoulli trials needed to get one success, supported on the set { 1, 2, 3, ...}"
17
+ @description = "Discrete probability distribution that expresses the number of X Bernoulli trials needed to get one success, supported on the set { 1, 2, 3, ...}"
18
18
  configure(options)
19
19
  raise Croupier::InputParamsError, "Probability of success must be in the interval [0,1]" if params[:success] > 1 || params[:success] < 0
20
20
  end
@@ -7,7 +7,6 @@ module Croupier
7
7
  # sequence of Bernoulli trials before a specified (non-random)
8
8
  # number of failures (denoted size) occur.
9
9
  #
10
- # The parameter prob expresses the probability of success.
11
10
  # Wikipedia -- http://en.wikipedia.org/wiki/Negative_binomial_distribution
12
11
  class Nbinomial < ::Croupier::Distribution
13
12
 
@@ -28,14 +27,6 @@ module Croupier
28
27
  end
29
28
  end
30
29
 
31
- def base_geometric
32
- ::Croupier::Distributions::Geometric.new(success: params[:success])
33
- end
34
-
35
- def generate_geometrics(n)
36
- base_geometric.generate_sample(params[:size]*n)
37
- end
38
-
39
30
  def default_parameters
40
31
  {:success => 0.5, :size => 1}
41
32
  end
@@ -52,6 +43,16 @@ module Croupier
52
43
  :banner => "Negative binomial distribution. Discrete probability distribution of the number of successes in a sequence of Bernoulli trials before a specified (non-random) number of failures (denoted size) occur."
53
44
  }
54
45
  end
46
+
47
+ private
48
+ def base_geometric
49
+ ::Croupier::Distributions::Geometric.new(success: params[:success])
50
+ end
51
+
52
+ def generate_geometrics(n)
53
+ base_geometric.generate_sample(params[:size]*n)
54
+ end
55
+
55
56
  end
56
57
  end
57
58
  end
@@ -0,0 +1,3 @@
1
+ module Croupier
2
+ VERSION = "1.4.0"
3
+ end
@@ -0,0 +1,17 @@
1
+ context('** Bernoulli Distribution **')
2
+
3
+ context('ChiSquare Goodness of Fit test for default success p = 0.5')
4
+ croupier_bernoulli <- read.table("../generated_samples/bernoulli_05.data")
5
+ cs_result<-summary(goodfit(croupier_bernoulli$V1, type="binomial", method="ML", par=list(size=1, prob=0.5)))
6
+
7
+ test_that("p-value > 0.05, bernoulli, p = 0.5", {
8
+ expect_true(cs_result['Pearson',3] > 0.05)
9
+ })
10
+
11
+ context('ChiSquare Goodness of Fit test for success p = 0.75')
12
+ croupier_bernoulli <- read.table("../generated_samples/bernoulli_075.data")
13
+ cs_result<-summary(goodfit(croupier_bernoulli$V1, type="binomial", method="ML", par=list(size=1, prob=0.75)))
14
+
15
+ test_that("p-value > 0.05, bernoulli, p = 0.75", {
16
+ expect_true(cs_result['Pearson',3] > 0.05)
17
+ })
@@ -0,0 +1,17 @@
1
+ context('** Binomial Distribution **')
2
+
3
+ context('ChiSquare Goodness of Fit test for p=0.5, size=5')
4
+ croupier_binomial <- read.table("../generated_samples/binomial_05_5.data")
5
+ cs_result<-summary(goodfit(croupier_binomial$V1, type="binomial", method="ML", par=list(size=5, prob=0.5)))
6
+
7
+ test_that("p-value > 0.05, binomial, p = 0.5, size=5", {
8
+ expect_true(cs_result['Pearson',3] > 0.05)
9
+ })
10
+
11
+ context('ChiSquare Goodness of Fit test for p = 0.35, size=17')
12
+ croupier_binomial <- read.table("../generated_samples/binomial_035_17.data")
13
+ cs_result<-summary(goodfit(croupier_binomial$V1, type="binomial", method="ML", par=list(size=17, prob=0.35)))
14
+
15
+ test_that("p-value > 0.05, binomial, p=0.35, size=17", {
16
+ expect_true(cs_result['Pearson',3] > 0.05)
17
+ })
@@ -0,0 +1,52 @@
1
+ require "minitest/autorun"
2
+ require "croupier"
3
+ class TestDistributionsModule < MiniTest::Unit::TestCase
4
+
5
+ def test_list_of_all_distributions
6
+ all = Croupier::Distributions.all
7
+
8
+ assert all.size > 1
9
+
10
+ all.each{|d|
11
+ assert d.superclass == Croupier::Distribution
12
+ }
13
+
14
+ Croupier::Distributions.constants(false).each do |distrib|
15
+ d = ::Croupier::Distributions.const_get(distrib)
16
+ if d.is_a?(Class) && d.superclass == Croupier::Distribution
17
+ assert all.include?(d), "#{d.name} not included in array of all distributions"
18
+ end
19
+ end
20
+ end
21
+
22
+ def test_cli_names_list
23
+ list = Croupier::Distributions.list
24
+ Croupier::Distributions.all.each{|d|
25
+ assert list.include?(d.cli_name), "#{d.cli_name} not included in list"
26
+ }
27
+ end
28
+
29
+ def test_all_and_list_have_same_size
30
+ all = Croupier::Distributions.all
31
+ list = Croupier::Distributions.list
32
+ assert list.size == all.size
33
+ end
34
+
35
+ def test_dynamic_distribution_methods
36
+ Croupier::Distributions.list.each{|method|
37
+ assert Croupier::Distributions.respond_to?(method), "No response for #{method} method"
38
+ }
39
+ end
40
+
41
+ def test_dynamic_method_returns_right_distribution
42
+ Croupier::Distributions.list.each do |method|
43
+ distrib = Croupier::Distributions.send method
44
+ assert_equal distrib.class.cli_name, method
45
+ end
46
+
47
+ example = Croupier::Distributions.normal :mean => 33, :std => 21
48
+ assert_equal example.parameters[:mean], 33
49
+ assert_equal example.parameters[:std], 21
50
+ end
51
+
52
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: croupier
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-06-22 00:00:00.000000000 Z
13
+ date: 2012-06-25 00:00:00.000000000 Z
14
14
  dependencies: []
15
15
  description: Croupier is a Ruby gem to generate a random sample of numbers with a
16
16
  given probability distribution.
@@ -28,6 +28,8 @@ files:
28
28
  - lib/croupier/cli/application.rb
29
29
  - lib/croupier/cli/trollop.rb
30
30
  - lib/croupier/distribution.rb
31
+ - lib/croupier/distributions/bernoulli.rb
32
+ - lib/croupier/distributions/binomial.rb
31
33
  - lib/croupier/distributions/cauchy.rb
32
34
  - lib/croupier/distributions/exponential.rb
33
35
  - lib/croupier/distributions/geometric.rb
@@ -36,8 +38,12 @@ files:
36
38
  - lib/croupier/distributions/poisson.rb
37
39
  - lib/croupier/distributions/triangular.rb
38
40
  - lib/croupier/distributions/uniform.rb
41
+ - lib/croupier/distributions.rb
39
42
  - lib/croupier/exceptions.rb
43
+ - lib/croupier/version.rb
40
44
  - lib/croupier.rb
45
+ - test/distributions/R_tests/test_bernoulli.R
46
+ - test/distributions/R_tests/test_binomial.R
41
47
  - test/distributions/R_tests/test_cauchy.R
42
48
  - test/distributions/R_tests/test_exponential.R
43
49
  - test/distributions/R_tests/test_geometric.R
@@ -48,6 +54,7 @@ files:
48
54
  - test/distributions/R_tests/test_uniform.R
49
55
  - test/test_croupier_module.rb
50
56
  - test/test_distribution_class.rb
57
+ - test/test_distributions_module.rb
51
58
  - test/testsuite.R
52
59
  - bin/croupier
53
60
  homepage: https://github.com/xuanxu/croupier
@@ -78,6 +85,8 @@ signing_key:
78
85
  specification_version: 3
79
86
  summary: Samples of random numbers with specific probability distributions
80
87
  test_files:
88
+ - test/distributions/R_tests/test_bernoulli.R
89
+ - test/distributions/R_tests/test_binomial.R
81
90
  - test/distributions/R_tests/test_cauchy.R
82
91
  - test/distributions/R_tests/test_exponential.R
83
92
  - test/distributions/R_tests/test_geometric.R
@@ -88,4 +97,5 @@ test_files:
88
97
  - test/distributions/R_tests/test_uniform.R
89
98
  - test/test_croupier_module.rb
90
99
  - test/test_distribution_class.rb
100
+ - test/test_distributions_module.rb
91
101
  - test/testsuite.R