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