croupier 1.3.0 → 1.4.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.
- data/README.md +14 -0
- data/lib/croupier.rb +2 -0
- data/lib/croupier/cli/application.rb +6 -7
- data/lib/croupier/distribution.rb +0 -2
- data/lib/croupier/distributions.rb +29 -0
- data/lib/croupier/distributions/bernoulli.rb +44 -0
- data/lib/croupier/distributions/binomial.rb +53 -0
- data/lib/croupier/distributions/geometric.rb +1 -1
- data/lib/croupier/distributions/nbinomial.rb +10 -9
- data/lib/croupier/version.rb +3 -0
- data/test/distributions/R_tests/test_bernoulli.R +17 -0
- data/test/distributions/R_tests/test_binomial.R +17 -0
- data/test/test_distributions_module.rb +52 -0
- metadata +12 -2
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.
|
17
|
-
d =
|
18
|
-
|
19
|
-
|
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
|
|
@@ -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
|
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,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.
|
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-
|
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
|