random_variate_generator 0.0.2

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 783e457a4195aed607feeed3b41432a906d423fa
4
+ data.tar.gz: c0667a533666ddc64a0a05d730a4ff9180615ed0
5
+ SHA512:
6
+ metadata.gz: d3bff27c61c62a16cce9f323b6d3431131bc6e5c4941432c17f5b26378dbb16ac90f978effbb49ca62c2a2ad2e8f0976d9e4ce5b98839ff31d4b3562628a18e7
7
+ data.tar.gz: 0572ec13ed4254ef8489ba6d670363a95d1a1c60daf507d7bf6eb3df796fc58e02db9da6d586491671ed64890658db38d931405165b46e48e26c38b150766622
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Sergio Rivas
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,99 @@
1
+ # RandomVariateGenerator
2
+
3
+ Is a random number generator for random variate occurs.
4
+
5
+ You can generate random values from following distributions:
6
+
7
+ * Bernoulli
8
+ * Geometric
9
+ * Binomial
10
+ * Negative Binomial
11
+ * Exponential
12
+ * Poisson
13
+ * Triangular
14
+ * Normal
15
+ * Empirical
16
+ * Uniform (Discrete and Continuos)
17
+
18
+ ## Installation
19
+
20
+ Add this line to your application's Gemfile:
21
+
22
+ gem 'random_variate_generator'
23
+
24
+ And then execute:
25
+
26
+ $ bundle
27
+
28
+ Or install it yourself as:
29
+
30
+ $ gem install random_variate_generator
31
+
32
+ ## Usage
33
+
34
+ Add this in order to require funtionalities:
35
+
36
+ `gem 'random_variate_generator'`
37
+
38
+ You have two ways of generate random numbers.
39
+
40
+ ### Simple way (Examples)
41
+
42
+ * `RandomVariateGenerator::Random.exponential(lambda: 0.5)`
43
+ * `RandomVariateGenerator::Random.normal(mu: 0.5, sigma: 3)`
44
+ * `RandomVariateGenerator::Random.uniform(min: 0.5, max: 2)`
45
+ * `RandomVariateGenerator::Random.triangular(min: 0.5, mode: 1, max: 2)`
46
+ * `RandomVariateGenerator::Random.uniform_discrete(min: 0, max: 20)`
47
+ * `RandomVariateGenerator::Random.bernoulli(probability_of_success: 0.2)`
48
+ * `RandomVariateGenerator::Random.binomial(probability_of_success: 0.2, number_of_trials: 3)`
49
+ * `RandomVariateGenerator::Random.negative_binomial(probability_of_success: 0.2, number_of_success: 2)`
50
+ * `RandomVariateGenerator::Random.geometric(probability_of_success: 0.2)`
51
+ * `RandomVariateGenerator::Random.poisson(lambda: 3)`
52
+ * `RandomVariateGenerator::Random.empirical(probabilities: [0.1, 0.3, 0.6])`
53
+
54
+ ### Formal way (Examples)
55
+
56
+ With the formal way, you have to declare the random variate and then generate
57
+ the value with the method `generate_value`
58
+
59
+ ```ruby
60
+ require 'random_variate_generator'
61
+
62
+ exp = RandomVariateGenerator::ExponentialVariate.new(lambda: 3)
63
+ exp2 = RandomVariateGenerator::RandomVariate.create("exponential", lambda: 3)
64
+ nor = RandomVariateGenerator::RandomVariate.create("normal", mu: -10, sigma: 2)
65
+ unif = RandomVariateGenerator::UniformVariate.new(min: -3, max: 10)
66
+ tri = RandomVariateGenerator::TriangularVariate.new(min: 1, mode: 10, max: 15)
67
+ bin = RandomVariateGenerator::BinomialVariate.new(probability_of_success: 0.3, number_of_trials: 5)
68
+ bin_neg = RandomVariateGenerator::NegativeBinomialVariate.new(probability_of_success: 0.3, number_of_success: 2
69
+ bern = RandomVariateGenerator::BernoulliVariate.new (probability_of_success: 0.3)
70
+ poi = RandomVariateGenerator::PoissonVariate.new(lambda: 3)
71
+ empirical = RandomVariateGenerator::EmpiricalVariate.new(probabilities: [0.1, 0.3, 0.6])
72
+ geo = RandomVariateGenerator::GeometricVariate.new(probability_of_success: 0.3)
73
+
74
+ open("generated_values.txt","w"){|f|
75
+ 20000.times{
76
+ vals = [
77
+ exp.generate_value,
78
+ exp2.generate_value,
79
+ nor.generate_value,
80
+ unif.generate_value,
81
+ tri.generate_value,
82
+ bin.generate_value,
83
+ bin_neg.generate_value,
84
+ bern.generate_value,
85
+ poi.generate_value,
86
+ empirical.generate_value,
87
+ geo.generate_value]
88
+ f.puts vals.collect{|x| x.to_s}.join ", "
89
+ }
90
+ }
91
+ ```
92
+
93
+ ## Contributing
94
+
95
+ 1. Fork it ( http://github.com/<my-github-username>/random_variate_generator/fork )
96
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
97
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
98
+ 4. Push to the branch (`git push origin my-new-feature`)
99
+ 5. Create new Pull Request
@@ -0,0 +1,20 @@
1
+ require "random_variate_generator/version"
2
+
3
+ module RandomVariateGenerator
4
+ end
5
+
6
+ require "random_variate_generator/invalid_parameter_exception"
7
+ require "random_variate_generator/abstract_class_exception"
8
+ require "random_variate_generator/random"
9
+ require "random_variate_generator/random_variate"
10
+ require "random_variate_generator/exponential_variate"
11
+ require "random_variate_generator/uniform_variate"
12
+ require "random_variate_generator/triangular_variate"
13
+ require "random_variate_generator/normal_variate"
14
+ require "random_variate_generator/bernoulli_variate"
15
+ require "random_variate_generator/binomial_variate"
16
+ require "random_variate_generator/negative_binomial_variate"
17
+ require "random_variate_generator/geometric_variate"
18
+ require "random_variate_generator/poisson_variate"
19
+ require "random_variate_generator/empirical_variate"
20
+
@@ -0,0 +1,9 @@
1
+ module RandomVariateGenerator
2
+
3
+ class AbstractClassException < Exception
4
+ def initialize
5
+ super "This is a abstract class, this method must be implemented in a subclass"
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,18 @@
1
+ module RandomVariateGenerator
2
+
3
+ class BernoulliVariate < RandomVariate
4
+ def initialize(params = {})
5
+ if params[:probability_of_success]
6
+ @probability_of_success = params[:probability_of_success]
7
+ else
8
+ raise InvalidParameterException.new "Parameter :probability_of_success no specified"
9
+ end
10
+ raise InvalidParameterException.new "Parameter :probability_of_success must be greater than 0" if @probability_of_success <= 0
11
+ end
12
+
13
+ def generate_value
14
+ Random.bernoulli(:probability_of_success => @probability_of_success)
15
+ end
16
+ end
17
+
18
+ end
@@ -0,0 +1,25 @@
1
+ module RandomVariateGenerator
2
+
3
+ class BinomialVariate < RandomVariate
4
+ def initialize(params = {})
5
+ if params[:probability_of_success]
6
+ @probability_of_success = params[:probability_of_success]
7
+ else
8
+ raise InvalidParameterException.new "Parameter :probability_of_success no specified"
9
+ end
10
+ raise InvalidParameterException.new "Parameter :probability_of_success must be greater than 0" if @probability_of_success <= 0
11
+ if params[:number_of_trials]
12
+ @number_of_trials = params[:number_of_trials]
13
+ else
14
+ raise InvalidParameterException.new "Parameter :number_of_trials no specified"
15
+ end
16
+ raise InvalidParameterException.new "Parameter :number_of_trials must be greater than 0" if @number_of_trials <= 0
17
+ end
18
+
19
+ def generate_value
20
+ Random.binomial(:probability_of_success => @probability_of_success,
21
+ :number_of_trials => @number_of_trials)
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,17 @@
1
+ module RandomVariateGenerator
2
+
3
+ class EmpiricalVariate < RandomVariate
4
+ def initialize(params = {})
5
+ if params[:probabilities]
6
+ @probabilities = params[:probabilities]
7
+ else
8
+ raise InvalidParameterException.new "Parameter :probabilities no specified"
9
+ end
10
+ end
11
+
12
+ def generate_value
13
+ Random.empirical(:probabilities => @probabilities)
14
+ end
15
+ end
16
+
17
+ end
@@ -0,0 +1,18 @@
1
+ module RandomVariateGenerator
2
+
3
+ class ExponentialVariate < RandomVariate
4
+ def initialize(params = {})
5
+ if params[:lambda]
6
+ @lambda = params[:lambda]
7
+ else
8
+ raise InvalidParameterException.new "Parameter :lambda no specified"
9
+ end
10
+ raise InvalidParameterException.new "Parameter :lambda must be greater than 0" if @lambda <= 0
11
+ end
12
+
13
+ def generate_value
14
+ Random.exponential(:lambda => @lambda)
15
+ end
16
+ end
17
+
18
+ end
@@ -0,0 +1,18 @@
1
+ module RandomVariateGenerator
2
+
3
+ class GeometricVariate < RandomVariate
4
+ def initialize(params = {})
5
+ if params[:probability_of_success]
6
+ @probability_of_success = params[:probability_of_success]
7
+ else
8
+ raise InvalidParameterException.new "Parameter :probability_of_success no specified"
9
+ end
10
+ raise InvalidParameterException.new "Parameter :probability_of_success must be greater than 0" if @probability_of_success <= 0
11
+ end
12
+
13
+ def generate_value
14
+ Random.geometric(:probability_of_success => @probability_of_success)
15
+ end
16
+ end
17
+
18
+ end
@@ -0,0 +1,7 @@
1
+ module RandomVariateGenerator
2
+
3
+ class InvalidParameterException < Exception
4
+ end
5
+
6
+ end
7
+
@@ -0,0 +1,26 @@
1
+ module RandomVariateGenerator
2
+
3
+ class NegativeBinomialVariate < RandomVariate
4
+ def initialize(params = {})
5
+ if params[:probability_of_success]
6
+ @probability_of_success = params[:probability_of_success]
7
+ else
8
+ raise InvalidParameterException.new "Parameter :probability_of_success no specified"
9
+ end
10
+ raise InvalidParameterException.new "Parameter :probability_of_success must be greater than 0" if @probability_of_success <= 0
11
+ if params[:number_of_success]
12
+ @number_of_success = params[:number_of_success]
13
+ else
14
+ raise InvalidParameterException.new "Parameter :number_of_success no specified"
15
+ end
16
+ raise InvalidParameterException.new "Parameter :number_of_success must be greater than 0" if @number_of_success <= 0
17
+ end
18
+
19
+ def generate_value
20
+ Random.negative_binomial(
21
+ :probability_of_success => @probability_of_success,
22
+ :number_of_success => @number_of_success)
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,19 @@
1
+ module RandomVariateGenerator
2
+
3
+ class NormalVariate < RandomVariate
4
+ def initialize(params = {})
5
+ if params[:mu] && params[:sigma]
6
+ @mu = params[:mu]
7
+ @sigma = params[:sigma]
8
+ else
9
+ raise InvalidParameterException.new "Parameter :mu or :sigma no specified"
10
+ end
11
+ raise InvalidParameterException.new "Parameter :sigma must be greater than 0" if @sigma <= 0
12
+ end
13
+
14
+ def generate_value
15
+ Random.normal(:mu => @mu, :sigma => @sigma)
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,18 @@
1
+ module RandomVariateGenerator
2
+
3
+ class PoissonVariate < RandomVariate
4
+ def initialize(params = {})
5
+ if params[:lambda]
6
+ @lambda = params[:lambda]
7
+ else
8
+ raise InvalidParameterException.new "Parameter :lambda no specified"
9
+ end
10
+ raise InvalidParameterException.new "Parameter :lambda must be greater than 0" if @lambda <= 0
11
+ end
12
+
13
+ def generate_value
14
+ Random.poisson(:lambda => @lambda)
15
+ end
16
+ end
17
+
18
+ end
@@ -0,0 +1,97 @@
1
+ module RandomVariateGenerator
2
+
3
+ class Random
4
+
5
+ def self.exponential(params)
6
+ u = rand()
7
+ u = rand() while u <= 1e-7
8
+ -Math.log(u)/params[:lambda]
9
+ end
10
+
11
+ def self.normal(params)
12
+ x2pi = rand() * Math::PI
13
+ g2rad = Math.sqrt(-2.0 * Math.log(1.0 - rand()))
14
+ z = Math.cos(x2pi) * g2rad
15
+ params[:mu] + z*params[:sigma]
16
+ end
17
+
18
+ def self.uniform(params)
19
+ params[:min] + (params[:max]-params[:min]) * rand()
20
+ end
21
+
22
+ def self.triangular(params)
23
+ params[:min] *= 1.0
24
+ params[:mode] *= 1.0
25
+ params[:max] *= 1.0
26
+ u = rand()
27
+ c = 0.5
28
+ (params[:mode] - params[:min]) / (params[:max] - params[:min]) if params[:mode]
29
+ if u > c
30
+ u = 1.0 - u
31
+ c = 1.0 - c
32
+ params[:min], params[:max] = params[:max], params[:min]
33
+ end
34
+ params[:min] + (params[:max] - params[:min]) * (u * c) ** 0.5
35
+ end
36
+
37
+ def self.uniform_discrete(params)
38
+ uniform(:min => params[:min],
39
+ :max => (params[:max]+1)).to_i
40
+ end
41
+
42
+ def self.bernoulli(params)
43
+ (rand() < params[:probability_of_success])? 1 : 0
44
+ end
45
+
46
+ def self.binomial(params)
47
+ counter = 0
48
+ params[:number_of_trials].times{
49
+ counter += bernoulli(:probability_of_success => params[:probability_of_success])
50
+ }
51
+ counter
52
+ end
53
+
54
+ def self.negative_binomial(params)
55
+ counter = 0
56
+ success_counter = 0
57
+ while success_counter < params[:number_of_success]
58
+ counter += 1
59
+ success_counter += bernoulli(:probability_of_success => params[:probability_of_success])
60
+ end
61
+ counter
62
+ end
63
+ def self.geometric(params)
64
+ negative_binomial(:number_of_success => 1,
65
+ :probability_of_success => params[:probability_of_success])
66
+ end
67
+
68
+ def self.poisson(params)
69
+ cummulative_time = 0
70
+ cummulative_time += exponential(:lambda => params[:lambda])
71
+ counter = 0
72
+ while cummulative_time <= 1.0
73
+ counter += 1
74
+ cummulative_time += exponential(:lambda => params[:lambda])
75
+ end
76
+ counter
77
+ end
78
+
79
+ def self.empirical(params)
80
+ probs = params[:probabilities]
81
+ cda = []
82
+ acum = 0
83
+ probs.each{|x|
84
+ acum += x
85
+ cda << acum
86
+ }
87
+ cda << 1
88
+ cda.each{|x| x=1 if x > 1}
89
+ u = rand
90
+ index = 0
91
+ index += 1 while u > cda[index]
92
+ index
93
+ end
94
+
95
+ end
96
+
97
+ end
@@ -0,0 +1,38 @@
1
+ module RandomVariateGenerator
2
+
3
+ class RandomVariate
4
+
5
+ def self.create(distribution_name, args = {})
6
+ if distribution_name.to_s == "exponential"
7
+ return ExponentialVariate.new args
8
+ elsif distribution_name.to_s == "normal"
9
+ return NormalVariate.new args
10
+ elsif distribution_name.to_s == "uniform"
11
+ return UniformVariate.new args
12
+ elsif distribution_name.to_s == "triangular"
13
+ return TriangularVariate.new args
14
+ elsif distribution_name.to_s == "binomial"
15
+ return BinomialVariate.new args
16
+ elsif distribution_name.to_s == "geometric"
17
+ return GeometricVariate.new args
18
+ elsif distribution_name.to_s == "negative_binomial"
19
+ return NegativeBinomialVariate.new args
20
+ elsif distribution_name.to_s == "bernoulli"
21
+ return BernoulliVariate.new args
22
+ elsif distribution_name.to_s == "poisson"
23
+ return PoissonVariate.new args
24
+ elsif distribution_name.to_s == "empirical"
25
+ return EmpiricalVariate.new args
26
+ end
27
+ raise InvalidParameterException.new "Unknowed distribution"
28
+ end
29
+
30
+ def generate_value
31
+ raise AbstractClassException
32
+ end
33
+
34
+ #private_class_method :new
35
+
36
+ end
37
+
38
+ end
@@ -0,0 +1,22 @@
1
+ module RandomVariateGenerator
2
+
3
+ class TriangularVariate < RandomVariate
4
+ def initialize(params = {})
5
+ if params[:min] && params[:mode] && params[:max]
6
+ @min = params[:min]
7
+ @mode = params[:mode]
8
+ @max = params[:max]
9
+ else
10
+ raise InvalidParameterException.new "Parameter :min, :mode or :max no specified"
11
+ end
12
+ raise InvalidParameterException.new "Parameter :max must be greater than :mode" if @mode >= @max
13
+ raise InvalidParameterException.new "Parameter :max must be greater than :min" if @min >= @max
14
+ raise InvalidParameterException.new "Parameter :mode must be greater than :min" if @min >= @mode
15
+ end
16
+
17
+ def generate_value
18
+ Random.triangular(:min => @min, :mode => @mode, :max => @max)
19
+ end
20
+ end
21
+
22
+ end
@@ -0,0 +1,19 @@
1
+ module RandomVariateGenerator
2
+
3
+ class UniformVariate < RandomVariate
4
+ def initialize(params = {})
5
+ if params[:min] && params[:max]
6
+ @min = params[:min]
7
+ @max = params[:max]
8
+ else
9
+ raise InvalidParameterException.new "Parameter :min or :max no specified"
10
+ end
11
+ raise InvalidParameterException.new "Parameter :max must be greater than :min" if @min >= @max
12
+ end
13
+
14
+ def generate_value
15
+ Random.uniform(:min => @min,:max => @max)
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,3 @@
1
+ module RandomVariateGenerator
2
+ VERSION = "0.0.2"
3
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: random_variate_generator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Sergio Rivas
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Random value generator of several distributions
42
+ email:
43
+ - sergiorivas@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - LICENSE.txt
49
+ - README.md
50
+ - lib/random_variate_generator.rb
51
+ - lib/random_variate_generator/abstract_class_exception.rb
52
+ - lib/random_variate_generator/bernoulli_variate.rb
53
+ - lib/random_variate_generator/binomial_variate.rb
54
+ - lib/random_variate_generator/empirical_variate.rb
55
+ - lib/random_variate_generator/exponential_variate.rb
56
+ - lib/random_variate_generator/geometric_variate.rb
57
+ - lib/random_variate_generator/invalid_parameter_exception.rb
58
+ - lib/random_variate_generator/negative_binomial_variate.rb
59
+ - lib/random_variate_generator/normal_variate.rb
60
+ - lib/random_variate_generator/poisson_variate.rb
61
+ - lib/random_variate_generator/random.rb
62
+ - lib/random_variate_generator/random_variate.rb
63
+ - lib/random_variate_generator/triangular_variate.rb
64
+ - lib/random_variate_generator/uniform_variate.rb
65
+ - lib/random_variate_generator/version.rb
66
+ homepage: ''
67
+ licenses:
68
+ - MIT
69
+ metadata: {}
70
+ post_install_message:
71
+ rdoc_options: []
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubyforge_project:
86
+ rubygems_version: 2.2.1
87
+ signing_key:
88
+ specification_version: 4
89
+ summary: Random Variate Generator for Ruby
90
+ test_files: []