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 +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
|