croupier 1.4.0 → 1.5.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 CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  Croupier generates random samples of numbers with specific probability distributions.
4
4
 
5
+ [![Gem Version](https://badge.fury.io/rb/croupier.png)](http://badge.fury.io/rb/croupier)
6
+ [![Build Status](https://secure.travis-ci.org/xuanxu/croupier.png?branch=master)](http://travis-ci.org/xuanxu/croupier)
7
+
5
8
  ## Install
6
9
 
7
10
  You need to have Ruby and Rubygems installed in your system. Then install croupier with:
@@ -32,12 +35,14 @@ where:
32
35
 
33
36
  ### Available distributions and options
34
37
 
35
- Current version implements the following distributions:
38
+ Current version implements the following distributions:
36
39
 
37
40
  * Bernoulli
38
41
  * Binomial
39
42
  * Cauchy
43
+ * Degenerate
40
44
  * Exponential
45
+ * Gamma
41
46
  * Geometric
42
47
  * Negative binomial
43
48
  * Normal
@@ -79,12 +84,13 @@ To get a list of all available distributions/methods in Distributions module cal
79
84
 
80
85
  Croupier::Distributions.list
81
86
 
82
- ## How to generate a distribution.
87
+ ## How to generate a new distribution.
83
88
 
84
89
  There are several ways. The easiest one is to override ```generate_number``` or ```generate_sample``` (one is enough).
85
90
 
86
- Nonetheless there is another cool way to implement a distribution: implementing ```inv_cdf```. ``ìnv_cdf``` receives a
87
- parameter ```n``` that is a sample of a uniform distribution. It should return the inverse of the cdf applied to ```n```.
91
+ Nonetheless there is another cool way to implement a distribution: implementing ```inv_cdf```:
92
+
93
+ ```ìnv_cdf``` receives a parameter ```n``` that is a sample of a uniform distribution. It should return the inverse of the cdf applied to ```n```.
88
94
 
89
95
  ## License
90
96
 
@@ -93,3 +99,5 @@ Croupier is released under the MIT license.
93
99
  ## Credits
94
100
 
95
101
  Developed by Juanjo Bazán [`@xuanxu`](http://twitter.com/xuanxu) & Sergio Arbeo [`@serabe`](http://twitter.com/serabe)
102
+
103
+ Follow news and releases on twitter: [`@CroupierGem`](http://twitter.com/CroupierGem)
data/RUNNING_TESTS.md CHANGED
@@ -34,7 +34,7 @@ Other R packages needed:
34
34
  * triangle
35
35
  * vcd
36
36
 
37
- The test script will try to intall all dependencies if they are not found in your R installation.
37
+ The test script will try to install all dependencies if they are not found in your R installation.
38
38
  You can run the test/testsuite.R file:
39
39
 
40
40
  Using Rscript:
@@ -39,7 +39,7 @@ module Croupier
39
39
  if self.respond_to? :inv_cdf
40
40
  inv_cdf(rand)
41
41
  else
42
- generate_sample 1
42
+ generate_sample(1).first
43
43
  end
44
44
  end
45
45
 
@@ -0,0 +1,85 @@
1
+ module Croupier
2
+ module Distributions
3
+
4
+ #####################################################################
5
+ # CreditCard Distribution
6
+ # Continuous probability distribution describing resonance behavior.
7
+ #
8
+ class CreditCard < ::Croupier::Distribution
9
+
10
+ def initialize(options={})
11
+ @name = "CreditCard distribution"
12
+ @description = "Generates random credit card numbers."
13
+ configure(options)
14
+ end
15
+
16
+ def generate_number
17
+ n = "#{initial_value_by_card_type}#{initial_values}"
18
+ n += generate_random_string(15 - n.size)
19
+ n = n[0..14]
20
+ n + check_digit_for(n).to_s
21
+ end
22
+
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
+ def check_digit_for(n)
38
+ # Sum, every odd number should be doubled.
39
+ # If result has two digits, they should be summed up.
40
+ # This is equivalent to substracting 9
41
+ x = n.each_char.map do |x|
42
+ x.to_i
43
+ end.each_with_index.map do |x, i|
44
+ if i.even?
45
+ x = 2*x
46
+ (x >= 10) ? x - 9 : x
47
+ else
48
+ x
49
+ end
50
+ end.inject(&:+) % 10
51
+
52
+ return 0 if x == 0
53
+ 10 - x
54
+ end
55
+
56
+ def generate_random_string l
57
+ (1..l).map{ rand(10).to_s }.join ''
58
+ end
59
+
60
+ def initial_values
61
+ params[:initial_values].gsub /\D/, ''
62
+ end
63
+
64
+ def initial_value_by_card_type
65
+ return 3 if params[:american_express]
66
+ return 4 if params[:visa]
67
+ return 5 if params[:master_card]
68
+ return 6 if params[:discover]
69
+ ""
70
+ 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
+ end
84
+ end
85
+ end
@@ -0,0 +1,36 @@
1
+ module Croupier
2
+ module Distributions
3
+
4
+ #####################################################################
5
+ # Degenerate Distribution
6
+ # Discrete probability distribution that returns the same value.
7
+ class Degenerate < ::Croupier::Distribution
8
+
9
+ def initialize(options={})
10
+ @name = "Degenerate distribution"
11
+ @description = "Discrete probability distribution that returns the same value each time."
12
+ configure(options)
13
+ end
14
+
15
+ def generate_number
16
+ params[:constant]
17
+ end
18
+
19
+ def default_parameters
20
+ {:constant => 42.0}
21
+ end
22
+
23
+ def self.cli_name
24
+ "degenerate"
25
+ end
26
+
27
+ def self.cli_options
28
+ {:options => [
29
+ [:constant, 'value to be returned', {:type=>:float, :default => 42.0}]
30
+ ],
31
+ :banner => "Degenerate distribution. Discrete probability distribution that returns the same value each time."
32
+ }
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,65 @@
1
+ module Croupier
2
+ module Distributions
3
+
4
+ #####################################################################
5
+ # Gamma Distribution
6
+ # Family of continuous distributions with two parameters shape
7
+ # (defaults to 1) and scale (defaults to 1).
8
+ class Gamma < ::Croupier::Distribution
9
+
10
+ def initialize(options={})
11
+ @name = "Gamma distribution"
12
+ @description = "Family of continuous distributions with two parameters, shape and scale"
13
+ configure(options)
14
+ end
15
+
16
+ def generate_number
17
+ params[:scale] * (gen_xi - (1..params[:shape].floor).map { Math.log(1 - rand) }.inject(&:+) )
18
+ end
19
+
20
+ def default_parameters
21
+ {:shape => 1.0, :std => 1.0}
22
+ end
23
+
24
+ def self.cli_name
25
+ "gamma"
26
+ end
27
+
28
+ def self.cli_options
29
+ {:options => [
30
+ [:shape, 'shape of the distribution', {:type=>:float, :default => 1.0}],
31
+ [:scale, 'scale of the distribution', {:type=>:float, :default => 1.0}]
32
+ ],
33
+ :banner => "Family of continuous distributions with two parameters, shape and scale."
34
+ }
35
+ end
36
+
37
+ protected
38
+ # Based on Ahrens-Dieter acceptance-rejection method
39
+ # as described on Wikipedia:
40
+ # http://en.wikipedia.org/wiki/Gamma_distribution#Generating_gamma-distributed_random_variables
41
+ def gen_xi
42
+ delta = params[:shape] - params[:shape].floor
43
+ v_0 = Math::E / ( delta + Math::E )
44
+ eta = 1; xi = 0;
45
+
46
+ begin
47
+ # Generate thre independent uniformly distributed
48
+ # on interval (0,1]random variables
49
+ v_1 = 1 - rand; v_2 = 1 - rand; v_3 = 1 - rand;
50
+
51
+ # Generate a new xi.
52
+ if v_1 < v_0
53
+ xi = (v_2 ** (1/delta))
54
+ eta = v_3 * (xi ** (delta - 1))
55
+ else
56
+ xi = 1 - Math.log(v_2)
57
+ eta = v_3 * (Math::E ** (-xi))
58
+ end
59
+ end while eta > (xi ** (delta - 1)) * (Math::E ** -xi)
60
+
61
+ xi
62
+ end
63
+ end
64
+ end
65
+ end
@@ -1,3 +1,3 @@
1
1
  module Croupier
2
- VERSION = "1.4.0"
3
- end
2
+ VERSION = "1.5.0"
3
+ end
@@ -7,7 +7,7 @@ context('Kolmogorov-Smirnov test for default (location, scale) = (0,1)')
7
7
  croupier_cauchy <- read.table("../generated_samples/cauchy_0_1.data")
8
8
  ks_result<-ks.test(croupier_cauchy$V1, "pcauchy")
9
9
 
10
- test_that("p-value > 0.05", {
10
+ test_that("p-value > 0.05, cauchy, location=0, scale=1", {
11
11
  expect_true(ks_result$p.value > 0.05)
12
12
  })
13
13
 
@@ -19,7 +19,7 @@ context('Kolmogorov-Smirnov test for given (location, scale) = (12, 3)')
19
19
  croupier_cauchy <- read.table("../generated_samples/cauchy_12_3.data")
20
20
  ks_result<-ks.test(croupier_cauchy$V1, "pcauchy", location=12, scale=3)
21
21
 
22
- test_that("p-value > 0.05", {
22
+ test_that("p-value > 0.05, cauchy, location=12, scale=3", {
23
23
  expect_true(ks_result$p.value > 0.05)
24
24
  })
25
25
 
@@ -7,7 +7,7 @@ context('Kolmogorov-Smirnov test for default lambda = 1')
7
7
  croupier_exponential <- read.table("../generated_samples/exponential_1.data")
8
8
  ks_result<-ks.test(croupier_exponential$V1, "pexp")
9
9
 
10
- test_that("p-value > 0.05", {
10
+ test_that("p-value > 0.05, exponential, lambda=1", {
11
11
  expect_true(ks_result$p.value > 0.05)
12
12
  })
13
13
 
@@ -19,7 +19,7 @@ context('Kolmogorov-Smirnov test for given lambda = 1.6')
19
19
  croupier_exponential <- read.table("../generated_samples/exponential_1_6.data")
20
20
  ks_result<-ks.test(croupier_exponential$V1, "pexp", rate = 1.6)
21
21
 
22
- test_that("p-value > 0.05", {
22
+ test_that("p-value > 0.05, exponential, lambda=1.6", {
23
23
  expect_true(ks_result$p.value > 0.05)
24
24
  })
25
25
 
@@ -0,0 +1,27 @@
1
+ context('** Gamma Distribution **')
2
+
3
+ context('Kolmogorov-Smirnov test for gamma, shape=1.0, scale=1.0')
4
+ croupier_gamma <- read.table("../generated_samples/gamma_1_1.data")
5
+ ks_result<-ks.test(croupier_gamma$V1, "pgamma", shape = 1.0, scale=1.0)
6
+
7
+ test_that("p-value > 0.05 gamma, shape=1.0, scale=1.0", {
8
+ expect_true(ks_result$p.value > 0.05)
9
+ })
10
+
11
+ test_that("statistic converging to 0 gamma, shape=1.0, scale=1.0", {
12
+ expect_true(as.numeric(ks_result$statistic) < 0.05)
13
+ })
14
+
15
+
16
+ context('Kolmogorov-Smirnov test for gamma, shape=10.35, scale=2.5')
17
+ croupier_gamma <- read.table("../generated_samples/gamma_1035_25.data")
18
+ ks_result<-ks.test(croupier_gamma$V1, "pgamma", shape=10.35, scale=2.5)
19
+
20
+ test_that("p-value > 0.05 gamma, shape=10.35, scale=2.5", {
21
+ expect_true(ks_result$p.value > 0.05)
22
+ })
23
+
24
+ test_that("statistic converging to 0 gamma, shape=10.35, scale=2.5", {
25
+ expect_true(as.numeric(ks_result$statistic) < 0.05)
26
+ })
27
+
@@ -7,7 +7,7 @@ context('Kolmogorov-Smirnov test for default sample in [0,1]')
7
7
  croupier_uniform_0_1 <- read.table("../generated_samples/uniform_0_1.data")
8
8
  ks_result<-ks.test(croupier_uniform_0_1$V1, "punif")
9
9
 
10
- test_that("p-value > 0.05", {
10
+ test_that("p-value > 0.05, uniform, [0,1]", {
11
11
  expect_true(ks_result$p.value > 0.05)
12
12
  })
13
13
 
@@ -20,7 +20,7 @@ context('Kolmogorov-Smirnov test for sample with custom interval')
20
20
  croupier_uniform_5_33 <- read.table("../generated_samples/uniform_5_33.data")
21
21
  ks_result<-ks.test(croupier_uniform_5_33$V1, "punif", min = 5, max = 33)
22
22
 
23
- test_that("p-value > 0.05", {
23
+ test_that("p-value > 0.05, uniform, [5,33]", {
24
24
  expect_true(ks_result$p.value > 0.05)
25
25
  })
26
26
 
@@ -0,0 +1,60 @@
1
+ require "minitest/autorun"
2
+ require "croupier"
3
+ class TestDistributionClass < MiniTest::Unit::TestCase
4
+
5
+ def valid_options(optional={})
6
+ {}.merge(optional)
7
+ end
8
+
9
+ def credit_card(options={})
10
+ Croupier::Distributions::CreditCard.new(valid_options(options)).generate_number
11
+ end
12
+
13
+ def test_distribution_has_name_and_description
14
+ dist = Croupier::Distributions::CreditCard.new
15
+ assert_respond_to dist, 'name'
16
+ assert_respond_to dist, 'description'
17
+ end
18
+
19
+ def test_visa_starts_with_4
20
+ assert_equal "4", credit_card(visa: true)[0]
21
+ end
22
+
23
+ def test_american_express_starts_with_3
24
+ assert_equal "3", credit_card(american_express: true)[0]
25
+ end
26
+
27
+ def test_master_card_starts_with_5
28
+ assert_equal "5", credit_card(master_card: true)[0]
29
+ end
30
+
31
+ def test_discover_starts_with_6
32
+ assert_equal "6", credit_card(discover: true)[0]
33
+ end
34
+
35
+ def test_initial_values_are_placed_at_beginning
36
+ assert_equal "2345", credit_card(initial_values: "2345")[0..3]
37
+ end
38
+
39
+ def test_initial_values_are_placed_after_card_type_if_one_is_given
40
+ assert_equal "62345", credit_card(discover: true, initial_values: "2345")[0..4]
41
+ end
42
+
43
+ def test_initial_values_get_not_numbers_removed_before_placing_them
44
+ assert_equal "2345", credit_card(initial_values: "a2b3c4d5e")[0..3]
45
+ end
46
+
47
+ def test_generate_numbers_for_getting_a_15_chars_long_string
48
+ assert_equal 16, credit_card.size
49
+ assert_equal 16, credit_card(visa: true).size
50
+ assert_equal 16, credit_card(initial_values: "234566789-32").size
51
+ assert_equal 16, credit_card(initial_values: "01234567890123456789").size
52
+ end
53
+
54
+ def test_check_digit
55
+ assert_equal "2", credit_card(initial_values: "1234 5678 9012 345")[-1]
56
+ assert_equal "7", credit_card(initial_values: "1111 1111 1111 111")[-1]
57
+ assert_equal "8", credit_card(initial_values: "1111 1111 1111 101")[-1]
58
+ assert_equal "2", credit_card(visa: true, initial_values: "602das63276315242666")[-1]
59
+ end
60
+ end
@@ -0,0 +1,17 @@
1
+ require "minitest/autorun"
2
+ require "croupier"
3
+ class TestDistributionClass < MiniTest::Unit::TestCase
4
+
5
+ def test_distribution_has_name_and_description
6
+ dist = Croupier::Distributions::Degenerate.new
7
+ assert_respond_to dist, 'name'
8
+ assert_respond_to dist, 'description'
9
+ end
10
+
11
+ def test_returns_only_one_value
12
+ dist = Croupier::Distributions::Degenerate.new constant: 5.34
13
+ 5.times do
14
+ assert_equal 5.34, dist.generate_number
15
+ end
16
+ end
17
+ end
@@ -45,4 +45,14 @@ class TestDistributionClass < MiniTest::Unit::TestCase
45
45
  a = c.new
46
46
  assert a.generate_sample(3).all?
47
47
  end
48
+
49
+ def test_generate_number_not_returning_array_when_inv_cdf_not_implemented
50
+ c = Class.new(Croupier::Distribution) do
51
+ def generate_sample n
52
+ [1]*n
53
+ end
54
+ end
55
+ a = c.new
56
+ assert_kind_of Numeric, a.generate_number
57
+ end
48
58
  end
data/test/testsuite.R CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env Rscript
2
2
  #
3
3
  # This script runs all the R tests of the croupier gem for all the distributions.
4
- #
4
+ #
5
5
  # Running the script:
6
6
  # Option 1, Via Rscript:
7
7
  # $> Rscript testsuite.R
@@ -11,11 +11,11 @@
11
11
  #
12
12
  # Dependencies:
13
13
  # In order to run the tests you need to have installed the following packages:
14
- #
14
+ #
15
15
  # - testthat
16
16
  # - triangle
17
17
  # - vcd
18
- #
18
+ #
19
19
  # Croupier will try to install them automatically if they are not included
20
20
  # in your R installation.
21
21
 
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.0
4
+ version: 1.5.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-25 00:00:00.000000000 Z
13
+ date: 2013-05-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.
@@ -31,7 +31,10 @@ files:
31
31
  - lib/croupier/distributions/bernoulli.rb
32
32
  - lib/croupier/distributions/binomial.rb
33
33
  - lib/croupier/distributions/cauchy.rb
34
+ - lib/croupier/distributions/credit_card.rb
35
+ - lib/croupier/distributions/degenerate.rb
34
36
  - lib/croupier/distributions/exponential.rb
37
+ - lib/croupier/distributions/gamma.rb
35
38
  - lib/croupier/distributions/geometric.rb
36
39
  - lib/croupier/distributions/nbinomial.rb
37
40
  - lib/croupier/distributions/normal.rb
@@ -46,12 +49,15 @@ files:
46
49
  - test/distributions/R_tests/test_binomial.R
47
50
  - test/distributions/R_tests/test_cauchy.R
48
51
  - test/distributions/R_tests/test_exponential.R
52
+ - test/distributions/R_tests/test_gamma.R
49
53
  - test/distributions/R_tests/test_geometric.R
50
54
  - test/distributions/R_tests/test_nbinomial.R
51
55
  - test/distributions/R_tests/test_normal.R
52
56
  - test/distributions/R_tests/test_poisson.R
53
57
  - test/distributions/R_tests/test_triangular.R
54
58
  - test/distributions/R_tests/test_uniform.R
59
+ - test/distributions/minitest/test_credit_card.rb
60
+ - test/distributions/minitest/test_degenerate_distribution.rb
55
61
  - test/test_croupier_module.rb
56
62
  - test/test_distribution_class.rb
57
63
  - test/test_distributions_module.rb
@@ -69,18 +75,18 @@ require_paths:
69
75
  required_ruby_version: !ruby/object:Gem::Requirement
70
76
  none: false
71
77
  requirements:
72
- - - ! '>='
78
+ - - '>='
73
79
  - !ruby/object:Gem::Version
74
80
  version: '0'
75
81
  required_rubygems_version: !ruby/object:Gem::Requirement
76
82
  none: false
77
83
  requirements:
78
- - - ! '>='
84
+ - - '>='
79
85
  - !ruby/object:Gem::Version
80
86
  version: '0'
81
87
  requirements: []
82
88
  rubyforge_project:
83
- rubygems_version: 1.8.15
89
+ rubygems_version: 1.8.25
84
90
  signing_key:
85
91
  specification_version: 3
86
92
  summary: Samples of random numbers with specific probability distributions
@@ -89,12 +95,15 @@ test_files:
89
95
  - test/distributions/R_tests/test_binomial.R
90
96
  - test/distributions/R_tests/test_cauchy.R
91
97
  - test/distributions/R_tests/test_exponential.R
98
+ - test/distributions/R_tests/test_gamma.R
92
99
  - test/distributions/R_tests/test_geometric.R
93
100
  - test/distributions/R_tests/test_nbinomial.R
94
101
  - test/distributions/R_tests/test_normal.R
95
102
  - test/distributions/R_tests/test_poisson.R
96
103
  - test/distributions/R_tests/test_triangular.R
97
104
  - test/distributions/R_tests/test_uniform.R
105
+ - test/distributions/minitest/test_credit_card.rb
106
+ - test/distributions/minitest/test_degenerate_distribution.rb
98
107
  - test/test_croupier_module.rb
99
108
  - test/test_distribution_class.rb
100
109
  - test/test_distributions_module.rb