erv 0.3.1 → 0.3.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.
- checksums.yaml +4 -4
- data/lib/erv/discrete_uniform_distribution.rb +12 -17
- data/lib/erv/exponential_distribution.rb +1 -1
- data/lib/erv/gamma_distribution.rb +53 -20
- data/lib/erv/gaussian_distribution.rb +3 -3
- data/lib/erv/general_pareto_distribution.rb +26 -25
- data/lib/erv/geometric_distribution.rb +20 -19
- data/lib/erv/uniform_distribution.rb +1 -1
- data/lib/erv/version.rb +1 -1
- data/test/erv/discrete_uniform_distribution_test.rb +81 -0
- data/test/erv/gamma_distribution_test.rb +47 -0
- data/test/erv/general_pareto_distribution_test.rb +82 -0
- data/test/erv/geometric_distribution_test.rb +44 -0
- metadata +12 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f73f2bc514e8d23844ca2e1652bd0801f661679a
|
4
|
+
data.tar.gz: a772550f0c889fcbf411038c830add3fa144876c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 90c953b59a635bb02e4ee5e079147804b14a7d54033a0230f6d749bd9c3d67750ac6b3d722dfbb1d4a453c1158d1b51d311c348d0e5a3f67bcf3330715ae7d27
|
7
|
+
data.tar.gz: 0420a2bc62b45cf9453070a57b24dc7b7731de3fac657df3500f7404e5cf78de4d621d3c1043e00d9a6e6c1b8cdfc35fc0be7d7bbc207eb65ac4bb8b52188d97
|
@@ -1,8 +1,3 @@
|
|
1
|
-
if RUBY_PLATFORM == 'java'
|
2
|
-
require 'java'
|
3
|
-
java_import org.apache.commons.math3.distribution.UniformIntegerDistribution
|
4
|
-
end
|
5
|
-
|
6
1
|
require 'erv/distribution'
|
7
2
|
require 'erv/support/try'
|
8
3
|
|
@@ -10,23 +5,23 @@ require 'erv/support/try'
|
|
10
5
|
module ERV
|
11
6
|
|
12
7
|
class DiscreteUniformDistribution < Distribution
|
8
|
+
attr_reader :mean, :variance
|
9
|
+
|
13
10
|
def initialize(opts)
|
14
11
|
super(opts)
|
15
12
|
|
16
13
|
raise ArgumentError unless opts[:max_value]
|
17
|
-
max = opts[:max_value].to_i
|
18
|
-
min = opts[:min_value].try(:to_i) || 0
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
d = UniformIntegerDistribution.new(@rng, min, max)
|
23
|
-
# setup sampling function
|
24
|
-
@func = Proc.new { d.sample }
|
25
|
-
else
|
26
|
-
# setup sampling function
|
27
|
-
@func = Proc.new { min + @rng.uniform_int(max-min) }
|
28
|
-
end
|
14
|
+
@max = opts[:max_value].to_i
|
15
|
+
@min = opts[:min_value].try(:to_i) || 0
|
16
|
+
@mean = (@max + @min) / 2.0
|
17
|
+
# See https://en.wikipedia.org/wiki/Discrete_uniform_distribution
|
18
|
+
@variance = ((@max - @min + 1) ** 2 - 1) / 12.0
|
29
19
|
end
|
20
|
+
|
21
|
+
def sample
|
22
|
+
@min + @rng.rand(@max - @min)
|
23
|
+
end
|
24
|
+
|
30
25
|
end
|
31
26
|
|
32
27
|
end
|
@@ -21,7 +21,7 @@ module ERV
|
|
21
21
|
# starting from a random variable X ~ U(0,1), which is provided by the
|
22
22
|
# RNG, we can obtain a random variable Y ~ Exp(\lambda), with mean = 1 /
|
23
23
|
# \lambda, through the transformation: Y = - (1 / \lambda) ln X. see
|
24
|
-
# [
|
24
|
+
# [KROESE11], section 4.2.3.
|
25
25
|
- @mean * Math.log(@rng.rand)
|
26
26
|
end
|
27
27
|
end
|
@@ -1,32 +1,65 @@
|
|
1
|
-
if RUBY_PLATFORM == 'java'
|
2
|
-
require 'java'
|
3
|
-
JGammaDistribution = org.apache.commons.math3.distribution.GammaDistribution
|
4
|
-
end
|
5
|
-
|
6
1
|
require 'erv/distribution'
|
7
2
|
|
8
3
|
|
9
4
|
module ERV
|
10
|
-
|
5
|
+
# We refer to the formulation of the Gamma distribution adopted by [KROESE11]:
|
6
|
+
#
|
7
|
+
# f(x) = \frac{\lambda^{\alpha} x^{\alpha - 1} e^{-\lambda x}}{\Gamma(\alpha)}
|
8
|
+
#
|
9
|
+
# with \alpha > 0 being the shape parameter, \lambda > 0 being the scale
|
10
|
+
# parameter, and x > 0.
|
11
|
+
#
|
12
|
+
# (Note that, unlike [KROESE11] Wikipedia refers to the \beta parameter as the "rate".)
|
11
13
|
class GammaDistribution < Distribution
|
14
|
+
attr_accessor :mean, :variance
|
15
|
+
|
12
16
|
def initialize(opts)
|
13
17
|
super(opts)
|
14
18
|
|
15
|
-
raise ArgumentError unless opts[:
|
16
|
-
scale =
|
17
|
-
shape = opts[:shape].to_f
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
@func = Proc.new { d.sample }
|
25
|
-
else
|
26
|
-
# setup sampling function
|
27
|
-
@func = Proc.new { @rng.gamma(shape, scale) }
|
28
|
-
end
|
19
|
+
raise ArgumentError unless opts[:scale] and opts[:shape]
|
20
|
+
@scale = opts[:scale].to_f
|
21
|
+
@shape = opts[:shape].to_f
|
22
|
+
|
23
|
+
raise ArgumentError, "scale parameter must be greater than zero!" unless @scale > 0.0
|
24
|
+
raise ArgumentError, "shape parameter must be greater than zero!" unless @shape > 0.0
|
25
|
+
|
26
|
+
@mean = @shape / @scale
|
27
|
+
@variance = @shape / (@scale ** 2)
|
29
28
|
end
|
29
|
+
|
30
|
+
# We use Marsaglia and Tsang's sampling algorithm
|
31
|
+
#
|
32
|
+
# For more details, see [KROESE11], section 4.2.6, algorithm 4.33 and
|
33
|
+
# http://www.hongliangjie.com/2012/12/19/how-to-generate-gamma-random-variables/
|
34
|
+
def sample
|
35
|
+
gamrand(@shape, @scale)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def gamrand(shape, scale)
|
41
|
+
if shape >= 1.0
|
42
|
+
d = shape - 1.0 / 3
|
43
|
+
c = 1.0 / Math::sqrt(9 * d)
|
44
|
+
ok = false
|
45
|
+
until ok do
|
46
|
+
# Use box-muller algorithm (see [KROESE11], section 4.2.11, algorithm
|
47
|
+
# 4.47) to obtain z ~ N(0,1).
|
48
|
+
u_1 = @rng.rand
|
49
|
+
u_2 = @rng.rand
|
50
|
+
z = Math::sqrt(-2.0 * Math::log(u_1)) * Math::cos(2.0 * Math::PI * u_2)
|
51
|
+
if z > -1.0 / c
|
52
|
+
v = (1.0 + c * z) ** 3
|
53
|
+
u = @rng.rand
|
54
|
+
ok = Math::log(u) <= (0.5 * (z**2) + d - d * v + d * Math::log(v))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
d * v / scale;
|
58
|
+
else # 0 < @shape < 1
|
59
|
+
gamrand(shape + 1.0, scale) * (@rng.rand ** (1 / shape))
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
30
63
|
end
|
31
64
|
|
32
65
|
end
|
@@ -13,14 +13,14 @@ module ERV
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def sample
|
16
|
-
#
|
16
|
+
# Use Box-Muller algorithm (see [KROESE11], section 4.2.11, algorithm
|
17
17
|
# 4.47) to obtain x ~ N(0,1).
|
18
18
|
u_1 = @rng.rand
|
19
19
|
u_2 = @rng.rand
|
20
20
|
x = Math.sqrt(-2.0 * Math.log(u_1)) * Math.cos(2.0 * Math::PI * u_2)
|
21
21
|
|
22
|
-
#
|
23
|
-
# distribution.
|
22
|
+
# Use location-scale transformation to obtain a N(\mu, \sigma^2)
|
23
|
+
# distribution. See [KROESE11], section 3.1.2.2.
|
24
24
|
@mu + @sigma * x
|
25
25
|
end
|
26
26
|
|
@@ -1,42 +1,43 @@
|
|
1
|
-
if RUBY_PLATFORM == 'java'
|
2
|
-
require 'java'
|
3
|
-
java_import org.apache.commons.math3.distribution.UniformRealDistribution
|
4
|
-
end
|
5
|
-
|
6
1
|
require 'erv/distribution'
|
7
2
|
require 'erv/support/try'
|
8
3
|
|
9
4
|
|
10
5
|
module ERV
|
11
6
|
|
7
|
+
# See https://en.wikipedia.org/wiki/Generalized_Pareto_distribution
|
12
8
|
class GpdDistribution < Distribution
|
9
|
+
attr_accessor :mean, :variance
|
10
|
+
|
13
11
|
def initialize(opts)
|
14
12
|
super(opts)
|
15
13
|
|
16
14
|
raise ArgumentError unless opts[:scale] and opts[:shape]
|
17
|
-
scale = opts[:scale].to_f
|
18
|
-
shape = opts[:shape].to_f
|
19
|
-
location = opts[:location].try(:to_f) || 0.0
|
20
|
-
|
21
|
-
if
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
15
|
+
@scale = opts[:scale].to_f
|
16
|
+
@shape = opts[:shape].to_f
|
17
|
+
@location = opts[:location].try(:to_f) || 0.0
|
18
|
+
|
19
|
+
@mean = if @shape < 1.0
|
20
|
+
@location + @scale / (1.0 - @shape)
|
21
|
+
else
|
22
|
+
Infinity
|
23
|
+
end
|
24
|
+
|
25
|
+
@variance = if @shape < 0.5
|
26
|
+
(@scale ** 2.0) / (((1.0 - @shape) ** 2) * (1.0 - 2 * @shape))
|
27
|
+
else
|
28
|
+
Infinity
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def sample
|
33
|
+
u = 1.0 - @rng.rand
|
34
|
+
if @shape == 0.0
|
35
|
+
@location - @scale * Math::log(u)
|
31
36
|
else
|
32
|
-
|
33
|
-
@func = Proc.new {
|
34
|
-
# this algorithm was taken from wikipedia
|
35
|
-
u = 1.0 - @rng.uniform
|
36
|
-
location + (scale * ((u ** (-shape)) - 1.0) / shape)
|
37
|
-
}
|
37
|
+
@location + (@scale * ((u ** (- @shape)) - 1.0) / @shape)
|
38
38
|
end
|
39
39
|
end
|
40
|
+
|
40
41
|
end
|
41
42
|
|
42
43
|
end
|
@@ -1,32 +1,33 @@
|
|
1
|
-
|
2
|
-
require 'java'
|
3
|
-
JGeometricDistribution = org.apache.commons.math3.distribution.GeometricDistribution
|
4
|
-
end
|
1
|
+
require 'erv/distribution'
|
5
2
|
|
6
3
|
|
7
4
|
module ERV
|
8
5
|
|
6
|
+
# We adopt the following version of the geometric distribution:
|
7
|
+
#
|
8
|
+
# Pr(X = k) = (1 - p) ^ {k-1} * p
|
9
|
+
#
|
10
|
+
# See: https://en.wikipedia.org/wiki/Geometric_distribution
|
9
11
|
class GeometricDistribution < Distribution
|
12
|
+
attr_accessor :mean, :variance
|
13
|
+
|
10
14
|
def initialize(opts)
|
11
15
|
super(opts)
|
12
16
|
|
13
17
|
raise ArgumentError unless opts[:probability_of_success]
|
14
|
-
p = opts[:probability_of_success].to_f
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
@func = Proc.new { d.sample }
|
21
|
-
else
|
22
|
-
# setup sampling function
|
23
|
-
#
|
24
|
-
# WARNING: I HAVEN'T TRIED THIS CODE!!!
|
25
|
-
# Note that GSL implements the shifted version of the geometric
|
26
|
-
# distribution, so we might need to change the result (removing 1?)
|
27
|
-
@func = Proc.new { @rng.geometric(p) }
|
28
|
-
end
|
18
|
+
@p = opts[:probability_of_success].to_f
|
19
|
+
|
20
|
+
@mean = 1.0 / @p
|
21
|
+
@variance = (1.0 - @p) / (@p ** 2)
|
22
|
+
|
23
|
+
@ln_1_minus_p = Math::log(1 - @p)
|
29
24
|
end
|
25
|
+
|
26
|
+
def sample
|
27
|
+
u = @rng.rand
|
28
|
+
(Math::log(u) / @ln_1_minus_p).ceil
|
29
|
+
end
|
30
|
+
|
30
31
|
end
|
31
32
|
|
32
33
|
end
|
@@ -17,7 +17,7 @@ module ERV
|
|
17
17
|
def sample
|
18
18
|
# starting from a random variable X ~ U(0,1), which is provided by the
|
19
19
|
# RNG, we can obtain a random variable Y ~ U(a,b) through location-scale
|
20
|
-
# transformation: Y = a + (b-a) X. see [
|
20
|
+
# transformation: Y = a + (b-a) X. see [KROESE11], section 3.1.2.2.
|
21
21
|
@min + @range * @rng.rand
|
22
22
|
end
|
23
23
|
end
|
data/lib/erv/version.rb
CHANGED
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'erv/discrete_uniform_distribution'
|
4
|
+
|
5
|
+
describe ERV::DiscreteUniformDistribution do
|
6
|
+
|
7
|
+
NUM_SAMPLES = 10000
|
8
|
+
|
9
|
+
it 'should require at least a maximum parameter' do
|
10
|
+
lambda do
|
11
|
+
ERV::DiscreteUniformDistribution.new()
|
12
|
+
end.must_raise ArgumentError
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
context 'a (default) 1-parameter distribution' do
|
17
|
+
|
18
|
+
let :zero_to_sixty do
|
19
|
+
ERV::DiscreteUniformDistribution.new(max_value: 60)
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'sampling' do
|
23
|
+
|
24
|
+
it 'should allow sampling' do
|
25
|
+
zero_to_sixty.sample
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'moments' do
|
31
|
+
let :samples do
|
32
|
+
0.upto(NUM_SAMPLES).collect { zero_to_sixty.sample }
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should have the expected mean' do
|
36
|
+
sample_mean = samples.inject(0.0) {|s,x| s += x } / NUM_SAMPLES.to_f
|
37
|
+
sample_mean.must_be_within_epsilon zero_to_sixty.mean, 0.05
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should have the expected variance' do
|
41
|
+
sample_variance = samples.inject(0.0) {|s,x| s += (x - zero_to_sixty.mean) ** 2 } / NUM_SAMPLES.to_f
|
42
|
+
sample_variance.must_be_within_epsilon zero_to_sixty.variance, 0.05
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'a 2-parameter distribution' do
|
49
|
+
|
50
|
+
let :ten_to_ninety do
|
51
|
+
ERV::DiscreteUniformDistribution.new(min_value: 10, max_value: 90)
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'sampling' do
|
55
|
+
|
56
|
+
it 'should allow sampling' do
|
57
|
+
ten_to_ninety.sample
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'moments' do
|
63
|
+
|
64
|
+
let :samples do
|
65
|
+
0.upto(NUM_SAMPLES).collect { ten_to_ninety.sample }
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should have the expected mean' do
|
69
|
+
sample_mean = samples.inject(0.0) {|s,x| s += x } / NUM_SAMPLES.to_f
|
70
|
+
sample_mean.must_be_within_epsilon ten_to_ninety.mean, 0.05
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should have the expected variance' do
|
74
|
+
sample_variance = samples.inject(0.0) {|s,x| s += (x - ten_to_ninety.mean) ** 2 } / NUM_SAMPLES.to_f
|
75
|
+
sample_variance.must_be_within_epsilon ten_to_ninety.variance, 0.05
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'erv/gamma_distribution'
|
4
|
+
|
5
|
+
describe ERV::GammaDistribution do
|
6
|
+
|
7
|
+
NUM_SAMPLES = 20000
|
8
|
+
|
9
|
+
it 'should require the scale and shape parameters' do
|
10
|
+
lambda do
|
11
|
+
ERV::GammaDistribution.new()
|
12
|
+
end.must_raise ArgumentError
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'with a shape greater than one' do
|
16
|
+
|
17
|
+
let :gsgtone do
|
18
|
+
ERV::GammaDistribution.new(shape: 2.0, scale: 0.5)
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'sampling' do
|
22
|
+
|
23
|
+
it 'should allow sampling' do
|
24
|
+
gsgtone.sample
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'moments' do
|
30
|
+
let :samples do
|
31
|
+
0.upto(NUM_SAMPLES).collect { gsgtone.sample }
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should have the expected mean' do
|
35
|
+
sample_mean = samples.inject(0.0) {|s,x| s += x } / NUM_SAMPLES.to_f
|
36
|
+
sample_mean.must_be_within_epsilon gsgtone.mean, 0.05
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should have the expected variance' do
|
40
|
+
sample_variance = samples.inject(0.0) {|s,x| s += (x - gsgtone.mean) ** 2 } / NUM_SAMPLES.to_f
|
41
|
+
sample_variance.must_be_within_epsilon gsgtone.variance, 0.05
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'erv/general_pareto_distribution'
|
4
|
+
|
5
|
+
describe ERV::GpdDistribution do
|
6
|
+
|
7
|
+
NUM_SAMPLES = 50000
|
8
|
+
|
9
|
+
it 'should require scale and shape parameters' do
|
10
|
+
lambda do
|
11
|
+
ERV::GpdDistribution.new()
|
12
|
+
end.must_raise ArgumentError
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
context 'a (default) 2-parameter distribution' do
|
17
|
+
|
18
|
+
let :gpd_2params do
|
19
|
+
ERV::GpdDistribution.new(scale: 1.0, shape: 0.3)
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'sampling' do
|
23
|
+
|
24
|
+
it 'should allow sampling' do
|
25
|
+
gpd_2params.sample
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'moments' do
|
31
|
+
let :samples do
|
32
|
+
0.upto(NUM_SAMPLES).collect { gpd_2params.sample }
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should have the expected mean' do
|
36
|
+
sample_mean = samples.inject(0.0) {|s,x| s += x } / NUM_SAMPLES.to_f
|
37
|
+
sample_mean.must_be_within_epsilon gpd_2params.mean, 0.1
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should have the expected variance' do
|
41
|
+
sample_variance = samples.inject(0.0) {|s,x| s += (x - gpd_2params.mean) ** 2 } / NUM_SAMPLES.to_f
|
42
|
+
sample_variance.must_be_within_epsilon gpd_2params.variance, 0.1
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
context 'a 3-parameter distribution' do
|
50
|
+
|
51
|
+
let :gpd_3params do
|
52
|
+
ERV::GpdDistribution.new(scale: 1.0,
|
53
|
+
shape: 0.3,
|
54
|
+
location: 1.0)
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'sampling' do
|
58
|
+
|
59
|
+
it 'should allow sampling' do
|
60
|
+
gpd_3params.sample
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'moments' do
|
66
|
+
let :samples do
|
67
|
+
0.upto(NUM_SAMPLES).collect { gpd_3params.sample }
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should have the expected mean' do
|
71
|
+
sample_mean = samples.inject(0.0) {|s,x| s += x } / NUM_SAMPLES.to_f
|
72
|
+
sample_mean.must_be_within_epsilon gpd_3params.mean, 0.1
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'should have the expected variance' do
|
76
|
+
sample_variance = samples.inject(0.0) {|s,x| s += (x - gpd_3params.mean) ** 2 } / NUM_SAMPLES.to_f
|
77
|
+
sample_variance.must_be_within_epsilon gpd_3params.variance, 0.1
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'erv/geometric_distribution'
|
4
|
+
|
5
|
+
describe ERV::GeometricDistribution do
|
6
|
+
|
7
|
+
NUM_SAMPLES = 10000
|
8
|
+
|
9
|
+
it 'should require at least a probability of success parameter' do
|
10
|
+
lambda do
|
11
|
+
ERV::GeometricDistribution.new()
|
12
|
+
end.must_raise ArgumentError
|
13
|
+
end
|
14
|
+
|
15
|
+
let :gd do
|
16
|
+
ERV::GeometricDistribution.new(probability_of_success: 0.5)
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'sampling' do
|
20
|
+
|
21
|
+
it 'should allow sampling' do
|
22
|
+
gd.sample
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'moments' do
|
28
|
+
let :samples do
|
29
|
+
0.upto(NUM_SAMPLES).collect { gd.sample }
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should have the expected mean' do
|
33
|
+
sample_mean = samples.inject(0.0) {|s,x| s += x } / NUM_SAMPLES.to_f
|
34
|
+
sample_mean.must_be_within_epsilon gd.mean, 0.05
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should have the expected variance' do
|
38
|
+
sample_variance = samples.inject(0.0) {|s,x| s += (x - gd.mean) ** 2 } / NUM_SAMPLES.to_f
|
39
|
+
sample_variance.must_be_within_epsilon gd.variance, 0.05
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: erv
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mauro Tortonesi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-06-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -80,7 +80,7 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: 0.0.3
|
83
|
-
description: erv-0.3.
|
83
|
+
description: erv-0.3.2
|
84
84
|
email:
|
85
85
|
- mauro.tortonesi@unife.it
|
86
86
|
executables: []
|
@@ -108,7 +108,11 @@ files:
|
|
108
108
|
- lib/erv/uniform_distribution.rb
|
109
109
|
- lib/erv/version.rb
|
110
110
|
- test/erv/constant_distribution_test.rb
|
111
|
+
- test/erv/discrete_uniform_distribution_test.rb
|
111
112
|
- test/erv/distribution_test.rb
|
113
|
+
- test/erv/gamma_distribution_test.rb
|
114
|
+
- test/erv/general_pareto_distribution_test.rb
|
115
|
+
- test/erv/geometric_distribution_test.rb
|
112
116
|
- test/erv/mixture_distribution_test.rb
|
113
117
|
- test/erv/random_variable_test.rb
|
114
118
|
- test/test_helper.rb
|
@@ -132,13 +136,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
132
136
|
version: '0'
|
133
137
|
requirements: []
|
134
138
|
rubyforge_project:
|
135
|
-
rubygems_version: 2.6.
|
139
|
+
rubygems_version: 2.6.11
|
136
140
|
signing_key:
|
137
141
|
specification_version: 4
|
138
142
|
summary: Easy/elegant Ruby library providing support for random variable generation
|
139
143
|
test_files:
|
140
144
|
- test/erv/constant_distribution_test.rb
|
145
|
+
- test/erv/discrete_uniform_distribution_test.rb
|
141
146
|
- test/erv/distribution_test.rb
|
147
|
+
- test/erv/gamma_distribution_test.rb
|
148
|
+
- test/erv/general_pareto_distribution_test.rb
|
149
|
+
- test/erv/geometric_distribution_test.rb
|
142
150
|
- test/erv/mixture_distribution_test.rb
|
143
151
|
- test/erv/random_variable_test.rb
|
144
152
|
- test/test_helper.rb
|