croupier 1.6.0 → 2.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Gem Version](https://badge.fury.io/rb/croupier.png)](http://badge.fury.io/rb/croupier)
|
6
|
-
[![Build Status](https://secure.travis-ci.org/
|
6
|
+
[![Build Status](https://secure.travis-ci.org/croupiers/croupier-rb.png?branch=2.0)](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
|