croupier 1.6.0 → 2.0.0.rc1
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.
- checksums.yaml +7 -0
- data/README.md +2 -2
- data/Rakefile +7 -0
- data/lib/croupier/distribution.rb +115 -36
- data/lib/croupier/distribution_generator.rb +57 -0
- data/lib/croupier/distribution_generators/enumerator_block_generator.rb +23 -0
- data/lib/croupier/distribution_generators/enumerator_generator.rb +21 -0
- data/lib/croupier/distribution_generators/inverse_cdf_generator.rb +21 -0
- data/lib/croupier/distribution_generators/minimum_sample_generator.rb +24 -0
- data/lib/croupier/distribution_generators.rb +18 -0
- data/lib/croupier/distributions/bernoulli.rb +18 -25
- data/lib/croupier/distributions/binomial.rb +30 -29
- data/lib/croupier/distributions/cauchy.rb +22 -19
- data/lib/croupier/distributions/credit_card.rb +39 -29
- data/lib/croupier/distributions/degenerate.rb +16 -19
- data/lib/croupier/distributions/exponential.rb +18 -19
- data/lib/croupier/distributions/gamma.rb +66 -37
- data/lib/croupier/distributions/geometric.rb +19 -20
- data/lib/croupier/distributions/nbinomial.rb +22 -33
- data/lib/croupier/distributions/normal.rb +30 -34
- data/lib/croupier/distributions/poisson.rb +26 -25
- data/lib/croupier/distributions/triangular.rb +39 -25
- data/lib/croupier/distributions/uniform.rb +43 -19
- data/lib/croupier/distributions.rb +3 -4
- data/lib/croupier/version.rb +1 -1
- data/lib/croupier.rb +43 -6
- data/test/minitest/distribution_class/test_class_methods.rb +142 -0
- data/test/{test_distribution_class.rb → minitest/distribution_class/test_instance_methods.rb} +26 -28
- data/test/minitest/distribution_generator_class/test_class_methods.rb +24 -0
- data/test/minitest/distribution_generator_class/test_instance_methods.rb +35 -0
- data/test/minitest/distribution_generators/test_enumerator_block_generator.rb +31 -0
- data/test/minitest/distribution_generators/test_enumerator_generator.rb +33 -0
- data/test/minitest/distribution_generators/test_inverse_cdf_generator.rb +36 -0
- data/test/minitest/distribution_generators/test_minimum_sample_generator.rb +33 -0
- data/test/minitest/distributions/test_bernoulli_distribution.rb +13 -0
- data/test/minitest/distributions/test_binomial_distribution.rb +18 -0
- data/test/minitest/distributions/test_cauchy_distribution.rb +18 -0
- data/test/{distributions/minitest/test_credit_card.rb → minitest/distributions/test_credit_card_distribution.rb} +5 -0
- data/test/{distributions/minitest → minitest/distributions}/test_degenerate_distribution.rb +2 -2
- data/test/minitest/distributions/test_exponential_distribution.rb +13 -0
- data/test/minitest/distributions/test_gamma_distribution.rb +23 -0
- data/test/minitest/distributions/test_geometric_distribution.rb +13 -0
- data/test/minitest/distributions/test_normal_distribution.rb +17 -0
- data/test/minitest/distributions/test_poisson_distribution.rb +13 -0
- data/test/minitest/distributions/test_triangular_distribution.rb +26 -0
- data/test/minitest/distributions/test_uniform_distribution.rb +54 -0
- data/test/{test_croupier_module.rb → minitest/test_croupier_module.rb} +0 -0
- data/test/minitest/test_distribution_generators_module.rb +37 -0
- data/test/{test_distributions_module.rb → minitest/test_distributions_module.rb} +0 -0
- data/test/rtests.R +1 -0
- metadata +62 -44
- data/test/distributions/R_tests/test_bernoulli.R +0 -17
- data/test/distributions/R_tests/test_binomial.R +0 -17
- data/test/distributions/R_tests/test_cauchy.R +0 -28
- data/test/distributions/R_tests/test_exponential.R +0 -28
- data/test/distributions/R_tests/test_gamma.R +0 -27
- data/test/distributions/R_tests/test_geometric.R +0 -23
- data/test/distributions/R_tests/test_nbinomial.R +0 -17
- data/test/distributions/R_tests/test_normal.R +0 -52
- data/test/distributions/R_tests/test_poisson.R +0 -17
- data/test/distributions/R_tests/test_triangular.R +0 -28
- data/test/distributions/R_tests/test_uniform.R +0 -30
- data/test/testsuite.R +0 -37
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bf6d755404722c636a61587f2381ca5ff96ff62b
|
4
|
+
data.tar.gz: 2229632adcaab36de7a98fd4d1d6bca922485a6d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c03a5dcb2b26a88b3d6ccfb0bc205b72576ed9d4e802a10823ffca194ee291b8bbbe650870ba6a522e1c473fdee4216e64a1e6e7b78118366fa9f7182bd0a12f
|
7
|
+
data.tar.gz: 463e5689dc2fe99f689706925acfa1951689369617b9c4b58598f025e9e222661f79fd13f74976a3e3fff4c51b25053b767633703ca2c627e4639c00528fbab4
|
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
Croupier generates random samples of numbers with specific probability distributions.
|
4
4
|
|
5
5
|
[](http://badge.fury.io/rb/croupier)
|
6
|
-
[](http://travis-ci.org/croupiers/croupier-rb)
|
7
7
|
|
8
8
|
## Install
|
9
9
|
|
@@ -84,7 +84,7 @@ To get a list of all available distributions/methods in Distributions module cal
|
|
84
84
|
|
85
85
|
Croupier::Distributions.list
|
86
86
|
|
87
|
-
|
87
|
+
Distributions have a ```to_enum``` method that return an (infinity) enumerator, so you
|
88
88
|
can use any Enumerable method on it:
|
89
89
|
|
90
90
|
dist = Croupier::Distributions.exponential(:lambda => 17).to_enum
|
data/Rakefile
CHANGED
@@ -6,13 +6,107 @@ module Croupier
|
|
6
6
|
#
|
7
7
|
class Distribution
|
8
8
|
attr_accessor :parameters
|
9
|
-
|
9
|
+
attr_accessor :generator
|
10
|
+
|
11
|
+
class << self
|
12
|
+
# Sets the name property of the distribution.
|
13
|
+
# if given
|
14
|
+
#
|
15
|
+
# @param distribution_name [String,nil] the name of the distribution
|
16
|
+
# @return [String] current distribution name
|
17
|
+
def distribution_name distribution_name=nil
|
18
|
+
@distribution_name = distribution_name if distribution_name
|
19
|
+
@distribution_name
|
20
|
+
end
|
21
|
+
|
22
|
+
# Sets the description property of the distribution
|
23
|
+
# if given
|
24
|
+
#
|
25
|
+
# @param description [String,nil] description for the distribution
|
26
|
+
# @return [String] current description
|
27
|
+
def distribution_description description=nil
|
28
|
+
@distribution_description = description if description
|
29
|
+
@distribution_description
|
30
|
+
end
|
31
|
+
|
32
|
+
# Sets the generator class for this distribution, if given
|
33
|
+
#
|
34
|
+
# @param generator_class [Class] class for the generator for this distribution
|
35
|
+
# @return [Class] current generator class
|
36
|
+
def generator_class generator_class=nil
|
37
|
+
@generator_class = generator_class if generator_class
|
38
|
+
@generator_class
|
39
|
+
end
|
40
|
+
|
41
|
+
# Sets the generator block for this distribution, if given
|
42
|
+
#
|
43
|
+
# @param block [Proc] block for the generator
|
44
|
+
# @return [Proc] current generator block
|
45
|
+
def generator_block &block
|
46
|
+
@generator_block = block if block_given?
|
47
|
+
@generator_block
|
48
|
+
end
|
49
|
+
|
50
|
+
# Defines a hash with banner and all available CLI options.
|
51
|
+
# It is a hash with two keys:
|
52
|
+
# :banner => A string used as banner in the command line help
|
53
|
+
# :options => An array of arrays each one representing a CLI option
|
54
|
+
# with the following format:[:option, 'description', {hash of option params}]
|
55
|
+
# Example:
|
56
|
+
# {:banner => "This distribution generates only number 33",
|
57
|
+
# :options => [
|
58
|
+
# [:mean, 'The mean of the distribution', {:default => 33}],
|
59
|
+
# [:median, 'Median of the distribution',{:default => 33.0, :type => :float}]
|
60
|
+
# ]
|
61
|
+
# }
|
62
|
+
# @param options [Hash] new cli options
|
63
|
+
# return [Hash] current cli options
|
64
|
+
def cli_options options=nil
|
65
|
+
@cli_options = options if options
|
66
|
+
@cli_options || {}
|
67
|
+
end
|
68
|
+
|
69
|
+
# Sets the cli_name if given
|
70
|
+
#
|
71
|
+
# @param cli_name [String] new cli name
|
72
|
+
# @return [String] current cli name
|
73
|
+
def cli_name cli_name=nil
|
74
|
+
@cli_name = cli_name if cli_name
|
75
|
+
@cli_name
|
76
|
+
end
|
77
|
+
|
78
|
+
def default_parameters
|
79
|
+
Hash[(cli_options[:options]||{}).map do |name, desc, hash|
|
80
|
+
[name,hash[:default]]
|
81
|
+
end]
|
82
|
+
end
|
83
|
+
|
84
|
+
def method_missing(method, *args, &block) # :nodoc:
|
85
|
+
return super unless self.respond_to?(method)
|
86
|
+
generator = ::Croupier::DistributionGenerators.all.find{|d| d.method_name == method.to_s}
|
87
|
+
self.generator_class generator
|
88
|
+
self.generator_block &block
|
89
|
+
end
|
90
|
+
|
91
|
+
def respond_to?(method, include_private = false) # :nodoc:
|
92
|
+
::Croupier::DistributionGenerators.list.include?(method.to_s) || super(method, include_private)
|
93
|
+
end
|
94
|
+
end
|
10
95
|
|
11
96
|
# Initializes Distribution object and adds received options to the distribution parameters.
|
12
97
|
def initialize(options={})
|
13
|
-
@name = nil
|
14
|
-
@description = nil
|
15
98
|
configure(options)
|
99
|
+
create_generator
|
100
|
+
end
|
101
|
+
|
102
|
+
# Alias for `self.class.distribution_name`
|
103
|
+
# @return [String] distribution name
|
104
|
+
def name
|
105
|
+
self.class.distribution_name
|
106
|
+
end
|
107
|
+
|
108
|
+
def description
|
109
|
+
self.class.distribution_description
|
16
110
|
end
|
17
111
|
|
18
112
|
# Merge the hash of options into the default distribution parameters
|
@@ -22,25 +116,17 @@ module Croupier
|
|
22
116
|
|
23
117
|
# Default hash of distribution parameters
|
24
118
|
def default_parameters
|
25
|
-
|
119
|
+
self.class.default_parameters
|
26
120
|
end
|
27
121
|
|
28
122
|
# Main method to generate n random numbers using the current probability distribution
|
29
123
|
def generate_sample(n=1)
|
30
|
-
|
31
|
-
(1..n).map{ inv_cdf(rand) }
|
32
|
-
else
|
33
|
-
(1..n).map{ generate_number }
|
34
|
-
end
|
124
|
+
self.to_enum.take(n).to_a
|
35
125
|
end
|
36
126
|
|
37
127
|
# Generates one random number using the current probability distribution
|
38
128
|
def generate_number
|
39
|
-
|
40
|
-
inv_cdf(rand)
|
41
|
-
else
|
42
|
-
generate_sample(1).first
|
43
|
-
end
|
129
|
+
self.to_enum.next
|
44
130
|
end
|
45
131
|
|
46
132
|
# convenience method for lazy programmers
|
@@ -48,32 +134,25 @@ module Croupier
|
|
48
134
|
@parameters
|
49
135
|
end
|
50
136
|
|
51
|
-
#
|
52
|
-
|
53
|
-
# :banner => A string used as banner in the command line help
|
54
|
-
# :options => An array of arrays each one representing a CLI option
|
55
|
-
# with the following format:[:option, 'description', {hash of option params}]
|
56
|
-
# Example:
|
57
|
-
# {:banner => "This distribution generates only number 33",
|
58
|
-
# :options => [
|
59
|
-
# [:mean, 'The mean of the distribution', {:default => 33}],
|
60
|
-
# [:median, 'Median of the distribution',{:default => 33.0, :type => :float}]
|
61
|
-
# ]
|
62
|
-
# }
|
63
|
-
def self.cli_options
|
64
|
-
{:banner => nil, :options=>[]}
|
65
|
-
end
|
137
|
+
# Make Croupier::Distribution an Enumerable
|
138
|
+
include Enumerable
|
66
139
|
|
67
|
-
|
68
|
-
|
69
|
-
|
140
|
+
def each &block
|
141
|
+
if block_given?
|
142
|
+
self.to_enum.each &block
|
143
|
+
else
|
144
|
+
self.to_enum.each
|
145
|
+
end
|
70
146
|
end
|
71
147
|
|
72
148
|
def to_enum
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
149
|
+
@enum ||= @generator.to_enum.lazy
|
150
|
+
end
|
151
|
+
|
152
|
+
protected
|
153
|
+
def create_generator
|
154
|
+
if self.class.generator_class && self.class.generator_block
|
155
|
+
@generator = self.class.generator_class.new self, &self.class.generator_block
|
77
156
|
end
|
78
157
|
end
|
79
158
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Croupier
|
2
|
+
|
3
|
+
class DistributionGenerator
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
# Gets and optionally sets the method name for this generator
|
8
|
+
#
|
9
|
+
# @param new_method_name [String] new method name
|
10
|
+
# @return [String] current method name
|
11
|
+
def method_name new_method_name=nil
|
12
|
+
@method_name = new_method_name if new_method_name
|
13
|
+
@method_name
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :distribution
|
18
|
+
attr_reader :block
|
19
|
+
|
20
|
+
def initialize distribution, &block
|
21
|
+
@distribution = distribution
|
22
|
+
@block = block
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
# Accessor to distribution parameters
|
27
|
+
#
|
28
|
+
# @return [Hash<String,Object>] distribution parameters
|
29
|
+
def params
|
30
|
+
self.distribution.params
|
31
|
+
end
|
32
|
+
|
33
|
+
def croupier
|
34
|
+
::Croupier::Distributions
|
35
|
+
end
|
36
|
+
|
37
|
+
# @abstract Given some parameters, returns the minimum sample
|
38
|
+
# it can generate. Some generators generate more
|
39
|
+
# than one number each iteration.
|
40
|
+
#
|
41
|
+
# @return [Array<Numeric>] sample
|
42
|
+
def generate_minimum_sample
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_enum
|
47
|
+
Enumerator.new do |y|
|
48
|
+
loop do
|
49
|
+
sample = self.generate_minimum_sample
|
50
|
+
sample.each do |s|
|
51
|
+
y << s
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Croupier
|
2
|
+
|
3
|
+
module DistributionGenerators
|
4
|
+
|
5
|
+
# Call `enumerator_block` with a block
|
6
|
+
# that will be called as the parameter for
|
7
|
+
# Enumerator.new
|
8
|
+
class EnumeratorBlockGenerator < ::Croupier::DistributionGenerator
|
9
|
+
|
10
|
+
method_name "enumerator_block"
|
11
|
+
|
12
|
+
def initilize distribution, &block
|
13
|
+
super distribution, &block
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_enum
|
17
|
+
Enumerator.new do |y|
|
18
|
+
self.distribution.instance_exec(y,&self.block)
|
19
|
+
end.lazy
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Croupier
|
2
|
+
|
3
|
+
module DistributionGenerators
|
4
|
+
|
5
|
+
# Call `enumerator` with a block
|
6
|
+
# that returns an enumerator.
|
7
|
+
# First block argument is the Croupier::Distributions module
|
8
|
+
class EnumeratorGenerator < ::Croupier::DistributionGenerator
|
9
|
+
|
10
|
+
method_name "enumerator"
|
11
|
+
|
12
|
+
def initilize distribution, &block
|
13
|
+
super distribution, &block
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_enum
|
17
|
+
self.distribution.instance_exec(::Croupier::Distributions, &self.block).lazy
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Croupier
|
2
|
+
|
3
|
+
module DistributionGenerators
|
4
|
+
|
5
|
+
class InverseCDFGenerator < ::Croupier::DistributionGenerator
|
6
|
+
|
7
|
+
method_name "inv_cdf"
|
8
|
+
|
9
|
+
def initilize distribution, &block
|
10
|
+
super distribution, &block
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_enum
|
14
|
+
# Fix when final api is availble
|
15
|
+
croupier.uniform.to_enum.lazy.map do |n|
|
16
|
+
distribution.instance_exec(n, &self.block)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Croupier
|
2
|
+
|
3
|
+
module DistributionGenerators
|
4
|
+
|
5
|
+
class MinimumSampleGenerator < ::Croupier::DistributionGenerator
|
6
|
+
|
7
|
+
method_name "minimum_sample"
|
8
|
+
|
9
|
+
def initilize distribution, &block
|
10
|
+
super distribution, &block
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_enum
|
14
|
+
Enumerator.new do |y|
|
15
|
+
loop do
|
16
|
+
distribution.instance_exec(&self.block).each do |a|
|
17
|
+
y << a
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end.lazy
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Croupier
|
2
|
+
module DistributionGenerators
|
3
|
+
class << self
|
4
|
+
# An array containing all available Distribution classes
|
5
|
+
def all
|
6
|
+
::Croupier::DistributionGenerators.constants(false).each_with_object([]){|distrib,list|
|
7
|
+
d = ::Croupier::DistributionGenerators.const_get(distrib)
|
8
|
+
list << d if (d.is_a?(Class) && d.superclass == Croupier::DistributionGenerator)
|
9
|
+
}.uniq.compact
|
10
|
+
end
|
11
|
+
|
12
|
+
# list of all available distribution names (and methods on Distributions module)
|
13
|
+
def list
|
14
|
+
self.all.map(&:method_name).sort
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -8,37 +8,30 @@ module Croupier
|
|
8
8
|
# Equivalent to a Binomial(1,p)
|
9
9
|
class Bernoulli < ::Croupier::Distribution
|
10
10
|
|
11
|
-
|
12
|
-
|
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
|
11
|
+
distribution_name "Bernoulli distribution"
|
12
|
+
distribution_description "Discrete probability distribution taking value 1 with success probability p and value 0 with failure probability 1-p."
|
17
13
|
|
18
|
-
|
19
|
-
binomial_1_p.generate_number
|
20
|
-
end
|
14
|
+
cli_name "bernoulli"
|
21
15
|
|
22
|
-
|
23
|
-
|
24
|
-
|
16
|
+
cli_options({
|
17
|
+
options: [
|
18
|
+
[:success, 'success probability', {type: :float, short: "-p", default: 0.5}]
|
19
|
+
],
|
20
|
+
banner: "Bernoulli distribution. Discrete probability distribution taking value 1 with success probability p and value 0 with failure probability 1-p."
|
21
|
+
})
|
25
22
|
|
26
|
-
|
27
|
-
|
23
|
+
enumerator do |c|
|
24
|
+
c.binomial(success: success, size: 1).to_enum.lazy
|
28
25
|
end
|
29
26
|
|
30
|
-
def
|
31
|
-
|
32
|
-
|
33
|
-
],
|
34
|
-
:banner => "Bernoulli distribution. Discrete probability distribution taking value 1 with success probability p and value 0 with failure probability 1-p."
|
35
|
-
}
|
27
|
+
def initialize(options={})
|
28
|
+
super(options)
|
29
|
+
raise Croupier::InputParamsError, "Probability of success must be in the interval [0,1]" if params[:success] > 1 || params[:success] < 0
|
36
30
|
end
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
@binomial_1_p ||= ::Croupier::Distributions::Binomial.new(:success => params[:success], :size => 1)
|
31
|
+
|
32
|
+
def success
|
33
|
+
params[:success]
|
41
34
|
end
|
42
35
|
end
|
43
36
|
end
|
44
|
-
end
|
37
|
+
end
|
@@ -8,44 +8,45 @@ module Croupier
|
|
8
8
|
# probability p
|
9
9
|
class Binomial < ::Croupier::Distribution
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
distribution_name "Binomial distribution"
|
12
|
+
|
13
|
+
distribution_description "Discrete probability distribution of the number of successes in a sequence of Bernoulli trials."
|
14
|
+
|
15
|
+
cli_name "binomial"
|
16
|
+
|
17
|
+
cli_options({
|
18
|
+
options: [
|
19
|
+
[:size, 'number of trials', {type: :integer, default: 1}],
|
20
|
+
[:success, 'success probability of each trial', {type: :float, short: "-p", default: 0.5}]
|
21
|
+
],
|
22
|
+
banner: "Binomial distribution. Discrete probability distribution of the number of successes in a sequence of Bernoulli trials."
|
23
|
+
})
|
17
24
|
|
18
|
-
|
19
|
-
|
20
|
-
s = 0
|
25
|
+
enumerator_block do |y|
|
26
|
+
g = ::Croupier::Distributions.geometric(success: success).to_enum.lazy
|
21
27
|
loop do
|
22
|
-
s
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
+
x = -1; s = 0
|
29
|
+
|
30
|
+
begin
|
31
|
+
s += g.next
|
32
|
+
x += 1
|
33
|
+
end while s <= size
|
28
34
|
|
29
|
-
|
30
|
-
|
35
|
+
y << x
|
36
|
+
end
|
31
37
|
end
|
32
38
|
|
33
|
-
def
|
34
|
-
|
39
|
+
def initialize(options={})
|
40
|
+
super(options)
|
41
|
+
raise Croupier::InputParamsError, "Probability of success must be in the interval [0,1]" if params[:success] > 1 || params[:success] < 0
|
35
42
|
end
|
36
43
|
|
37
|
-
def
|
38
|
-
|
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
|
+
def size
|
45
|
+
params[:size]
|
44
46
|
end
|
45
47
|
|
46
|
-
|
47
|
-
|
48
|
-
@base_geometric ||= ::Croupier::Distributions::Geometric.new(success: params[:success])
|
48
|
+
def success
|
49
|
+
params[:success]
|
49
50
|
end
|
50
51
|
|
51
52
|
end
|
@@ -7,32 +7,35 @@ module Croupier
|
|
7
7
|
#
|
8
8
|
class Cauchy < ::Croupier::Distribution
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
configure(options)
|
14
|
-
raise Croupier::InputParamsError, "Invalid scale value, it must be positive" unless params[:scale] > 0
|
15
|
-
end
|
10
|
+
distribution_name "Cauchy distribution"
|
11
|
+
|
12
|
+
distribution_description "Continuous probability distribution describing resonance behavior"
|
16
13
|
|
17
|
-
|
18
|
-
|
14
|
+
cli_name "cauchy"
|
15
|
+
|
16
|
+
cli_options({
|
17
|
+
options: [
|
18
|
+
[:location, 'location param', {type: :float, default:0.0}],
|
19
|
+
[:scale, 'scale param', {type: :float, default: 1.0}],
|
20
|
+
],
|
21
|
+
banner: "Cauchy continuous distribution. Generate numbers following a Cauchy distribution with location and scale parameters"
|
22
|
+
})
|
23
|
+
|
24
|
+
inv_cdf do |n|
|
25
|
+
location + (scale * Math.tan( Math::PI * (0.5 - n)))
|
19
26
|
end
|
20
27
|
|
21
|
-
def
|
22
|
-
|
28
|
+
def initialize(options={})
|
29
|
+
super(options)
|
30
|
+
raise Croupier::InputParamsError, "Invalid scale value, it must be positive" unless params[:scale] > 0
|
23
31
|
end
|
24
32
|
|
25
|
-
def
|
26
|
-
|
33
|
+
def location
|
34
|
+
params[:location]
|
27
35
|
end
|
28
36
|
|
29
|
-
def
|
30
|
-
|
31
|
-
[:location, 'location param', {:type=>:float, :default => 0.0}],
|
32
|
-
[:scale, 'scale param', {:type=>:float, :default => 1.0}],
|
33
|
-
],
|
34
|
-
:banner => "Cauchy continuous distribution. Generate numbers following a Cauchy distribution with location and scale parameters"
|
35
|
-
}
|
37
|
+
def scale
|
38
|
+
params[:scale]
|
36
39
|
end
|
37
40
|
end
|
38
41
|
end
|
@@ -7,10 +7,46 @@ module Croupier
|
|
7
7
|
#
|
8
8
|
class CreditCard < ::Croupier::Distribution
|
9
9
|
|
10
|
+
distribution_name "CreditCard distribution"
|
11
|
+
|
12
|
+
distribution_description "Generates random credit card numbers."
|
13
|
+
|
14
|
+
cli_name "credit_card"
|
15
|
+
|
16
|
+
cli_options({
|
17
|
+
options: [
|
18
|
+
[:master_card, 'master card type', {type: :boolean, default: false}],
|
19
|
+
[:american_express, 'american express card type', {type: :boolean, default: false}],
|
20
|
+
[:visa, 'visa card type', {type: :boolean, default: false}],
|
21
|
+
[:discover, 'discover card type', {type: :boolean, default: false}],
|
22
|
+
[:initial_values, 'initial values for the credit card. They will be place after card type if one is given.', {type: :string, default: ""}]
|
23
|
+
],
|
24
|
+
banner: "Credit Card distribution. Generate random card numbers"
|
25
|
+
})
|
26
|
+
|
27
|
+
# Returns a lambda that completes
|
28
|
+
# the credit card number up to
|
29
|
+
# 15 numbers.
|
30
|
+
def fill_number
|
31
|
+
->(n) { "#{n}#{generate_random_string(15-n.size)}"[0..14] }
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns a lambda that adds
|
35
|
+
# the checksum number
|
36
|
+
def add_checksum
|
37
|
+
->(n) { "#{n}#{check_digit_for(n)}" }
|
38
|
+
end
|
39
|
+
|
40
|
+
enumerator do |c|
|
41
|
+
c.degenerate(constant: init).to_enum.lazy.map(&fill_number).map(&add_checksum)
|
42
|
+
end
|
43
|
+
|
10
44
|
def initialize(options={})
|
11
|
-
|
12
|
-
|
13
|
-
|
45
|
+
super(options)
|
46
|
+
end
|
47
|
+
|
48
|
+
def init
|
49
|
+
"#{initial_value_by_card_type}#{initial_values}"
|
14
50
|
end
|
15
51
|
|
16
52
|
def generate_number
|
@@ -20,20 +56,6 @@ module Croupier
|
|
20
56
|
n + check_digit_for(n).to_s
|
21
57
|
end
|
22
58
|
|
23
|
-
def default_parameters
|
24
|
-
{
|
25
|
-
:master_card => false,
|
26
|
-
:american_express => false,
|
27
|
-
:discover => false,
|
28
|
-
:visa => false,
|
29
|
-
:initial_values => ""
|
30
|
-
}
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.cli_name
|
34
|
-
"credit_card"
|
35
|
-
end
|
36
|
-
|
37
59
|
def check_digit_for(n)
|
38
60
|
# Sum, every odd number should be doubled.
|
39
61
|
# If result has two digits, they should be summed up.
|
@@ -68,18 +90,6 @@ module Croupier
|
|
68
90
|
return 6 if params[:discover]
|
69
91
|
""
|
70
92
|
end
|
71
|
-
|
72
|
-
def self.cli_options
|
73
|
-
{:options => [
|
74
|
-
[:master_card, 'master card type', {:type=>:boolean, :default => false}],
|
75
|
-
[:american_express, 'american express card type', {:type=>:boolean, :default => false}],
|
76
|
-
[:visa, 'visa card type', {:type=>:boolean, :default => false}],
|
77
|
-
[:discover, 'discover card type', {:type=>:boolean, :default => false}],
|
78
|
-
[:initial_values, 'initial values for the credit card. They will be place after card type if one is given.', {:type=>:string, :default => ""}]
|
79
|
-
],
|
80
|
-
:banner => "Credit Card distribution. Generate random card numbers"
|
81
|
-
}
|
82
|
-
end
|
83
93
|
end
|
84
94
|
end
|
85
95
|
end
|