croupier 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
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