capricious 0.1.0 → 0.2.1
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/CHANGES +15 -2
- data/VERSION +1 -1
- data/lib/capricious.rb +3 -0
- data/lib/capricious/biased_uniform.rb +35 -0
- data/lib/capricious/erlang.rb +48 -0
- data/lib/capricious/exponential.rb +46 -0
- data/lib/capricious/generic_prng.rb +16 -3
- data/lib/capricious/lfsr.rb +3 -4
- data/lib/capricious/mwc5.rb +7 -8
- data/lib/capricious/poisson.rb +15 -4
- data/lib/capricious/sample_sink.rb +10 -3
- data/lib/capricious/uniform.rb +25 -3
- data/spec/biased_uniform_spec.rb +35 -0
- data/spec/erlang_spec.rb +29 -0
- data/spec/exponential_spec.rb +28 -0
- data/spec/uniform_spec.rb +2 -4
- metadata +29 -9
data/CHANGES
CHANGED
@@ -1,9 +1,22 @@
|
|
1
|
-
version 0.1
|
1
|
+
version 0.2.1
|
2
|
+
|
3
|
+
* 0.2.0 sneaked out the door with a stray debugging printf; this is a paper-bag release.
|
4
|
+
|
5
|
+
version 0.2.0 (6cebdd8c2574be71b9f9575542903960b22aa568)
|
6
|
+
|
7
|
+
* Improved documentation.
|
8
|
+
* Added Erlang distribution.
|
9
|
+
* Added exponential distribution.
|
10
|
+
* Added #expected_mean and #expected_variance methods to all distribution simulators.
|
11
|
+
* Added biased uniform distribution (i.e. uniform distributions with ranges other than 0..1).
|
12
|
+
* Substantial speed improvements to MWC generator.
|
13
|
+
|
14
|
+
version 0.1.0 (369ba2f9eb0b921b24efa5b75aa34478d0a443af)
|
2
15
|
|
3
16
|
* added multiply-with-carry based PRNG (algorithm due to George Marsaglia)
|
4
17
|
* added Poisson distribution
|
5
18
|
|
6
|
-
version 0.0.2
|
19
|
+
version 0.0.2 (8d28e1f4065ba8cc249722f2b4b4add091cb9dfb)
|
7
20
|
|
8
21
|
* initial release
|
9
22
|
* linear-feedback shift register based PRNG
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1
|
1
|
+
0.2.1
|
data/lib/capricious.rb
CHANGED
@@ -0,0 +1,35 @@
|
|
1
|
+
# capricious/biased_uniform.rb: biased uniform-distribution PRNG, with specifiable max and min and selectable source-randomness policy
|
2
|
+
#
|
3
|
+
# Copyright:: Copyright (c) 2010 Red Hat, Inc.
|
4
|
+
# Author:: William Benton <willb@redhat.com>
|
5
|
+
# License:: http://www.apache.org/licenses/LICENSE-2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
|
19
|
+
require 'capricious/uniform'
|
20
|
+
|
21
|
+
module Capricious
|
22
|
+
# Models a uniform distribution, parameterized on minimum and maximum values.
|
23
|
+
class BiasedUniform < Uniform
|
24
|
+
def initialize(min=Uniform::UNIFORM_MIN, max=Uniform::UNIFORM_MAX, seed=nil, policy=MWC5, keep_stats=false)
|
25
|
+
@min = min
|
26
|
+
@max = max
|
27
|
+
prng_initialize(seed, policy, keep_stats)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
def next_value
|
32
|
+
(@prng.next_f * (max - min)) + min
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# capricious/exponential.rb: Erlang distribution PRNG, with selectable source-randomness policy
|
2
|
+
#
|
3
|
+
# Copyright:: Copyright (c) 2010 Red Hat, Inc.
|
4
|
+
# Author:: William Benton <willb@redhat.com>
|
5
|
+
# License:: http://www.apache.org/licenses/LICENSE-2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
|
19
|
+
require 'capricious/generic_prng'
|
20
|
+
require 'capricious/exponential'
|
21
|
+
|
22
|
+
module Capricious
|
23
|
+
# Models the Erlang distribution, parameterized on the lambda value of the
|
24
|
+
# underlying exponential distribution and a shape parameter.
|
25
|
+
class Erlang
|
26
|
+
include PRNG
|
27
|
+
|
28
|
+
attr_reader :expected_mean, :expected_variance
|
29
|
+
|
30
|
+
# Initializes a new Erlang distribution. =l= is the lambda parameter and
|
31
|
+
# =shape= is the shape parameter; =seed=, =policy=, and =keep_stats= are
|
32
|
+
# as in =PRNG=.
|
33
|
+
def initialize(l, shape, seed=nil, policy=MWC5, keep_stats=false)
|
34
|
+
@shape = shape
|
35
|
+
@expected_mean = shape / l.to_f
|
36
|
+
@expected_variance = shape / (l * l).to_f
|
37
|
+
@expo = Exponential.new(l, seed, policy, keep_stats)
|
38
|
+
prng_initialize(seed, policy, keep_stats)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
def next_value
|
43
|
+
sum = 0.0
|
44
|
+
@shape.times { sum += @expo.next }
|
45
|
+
sum
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# capricious/exponential.rb: Exponential distribution PRNG, with selectable source-randomness policy
|
2
|
+
#
|
3
|
+
# Copyright:: Copyright (c) 2010 Red Hat, Inc.
|
4
|
+
# Author:: William Benton <willb@redhat.com>
|
5
|
+
# License:: http://www.apache.org/licenses/LICENSE-2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
|
19
|
+
require 'capricious/generic_prng'
|
20
|
+
|
21
|
+
module Capricious
|
22
|
+
# Exponential-distribution PRNG
|
23
|
+
class Exponential
|
24
|
+
include PRNG
|
25
|
+
|
26
|
+
attr_reader :expected_mean, :expected_variance
|
27
|
+
|
28
|
+
# Initializes a new distribution. =l= is the lambda parameter; =seed=,
|
29
|
+
# =policy=, and =keep_stats= are as in =PRNG=.
|
30
|
+
def initialize(l, seed=nil, policy=MWC5, keep_stats=false)
|
31
|
+
@expected_mean = 1 / l.to_f
|
32
|
+
@expected_variance = 1 / (l * l).to_f
|
33
|
+
prng_initialize(seed, policy, keep_stats)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
def next_value
|
38
|
+
u = @prng.next_f
|
39
|
+
while u == 0.0 || u == 1.0
|
40
|
+
u = @prng.next_f
|
41
|
+
end
|
42
|
+
|
43
|
+
-expected_mean * Math.log(u)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# capricious/generic_prng.rb: generic PRNG mixin with selectable source-randomness
|
2
2
|
#
|
3
|
-
# Copyright (c) 2010 Red Hat, Inc.
|
4
|
-
#
|
5
|
-
#
|
3
|
+
# Copyright:: Copyright (c) 2010 Red Hat, Inc.
|
4
|
+
# Author:: William Benton <willb@redhat.com>
|
5
|
+
# License:: http://www.apache.org/licenses/LICENSE-2.0
|
6
6
|
#
|
7
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
8
|
# you may not use this file except in compliance with the License.
|
@@ -21,8 +21,19 @@ require 'capricious/mwc5'
|
|
21
21
|
require 'capricious/sample_sink'
|
22
22
|
|
23
23
|
module Capricious
|
24
|
+
# Base mixin for distribution simulators. Manages an underlying PRNG and
|
25
|
+
# optional statistics. Mixing =PRNG= in to a simulator class will define
|
26
|
+
# =next= and =reset= methods as well as =@aggregate= and =@seed= attributes
|
27
|
+
# and a =@prng= instance variable. Simulator classes must define a
|
28
|
+
# =next_value= method that returns a value in the given distribution and
|
29
|
+
# should define =expected_mean= and =expected_variance= methods or
|
30
|
+
# attributes.
|
24
31
|
module PRNG
|
25
32
|
|
33
|
+
# Takes a seed, a policy, and whether or not to keep statistics in the
|
34
|
+
# =aggregate= attribute of the distribution object. If a simulator class
|
35
|
+
# overrides =initialize=, it must call =prng_initialize= from within its
|
36
|
+
# =initialize= method.
|
26
37
|
def initialize(seed=nil, policy=MWC5, keep_stats=false)
|
27
38
|
prng_initialize(seed, policy, keep_stats)
|
28
39
|
end
|
@@ -33,12 +44,14 @@ module Capricious
|
|
33
44
|
@aggregate = SampleSink.new if keep_stats
|
34
45
|
end
|
35
46
|
|
47
|
+
# Returns the next value from this simulator.
|
36
48
|
def next
|
37
49
|
val = next_value
|
38
50
|
@aggregate << val if @aggregate
|
39
51
|
val
|
40
52
|
end
|
41
53
|
|
54
|
+
# Resets the state of the underlying value.
|
42
55
|
def reset(seed=nil)
|
43
56
|
@prng.reset(seed)
|
44
57
|
@aggregate = SampleSink.new if @aggregate
|
data/lib/capricious/lfsr.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# capricious/lfsr.rb: linear-feedback shift register class
|
2
2
|
#
|
3
|
-
# Copyright (c) 2010 Red Hat, Inc.
|
4
|
-
#
|
5
|
-
#
|
3
|
+
# Copyright:: Copyright (c) 2010 Red Hat, Inc.
|
4
|
+
# Author:: William Benton <willb@redhat.com>
|
5
|
+
# License:: http://www.apache.org/licenses/LICENSE-2.0
|
6
6
|
#
|
7
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
8
|
# you may not use this file except in compliance with the License.
|
@@ -66,7 +66,6 @@ module Capricious
|
|
66
66
|
module SixtyFourBitShifter
|
67
67
|
MASK = 0xffffffffffffffff
|
68
68
|
SIZE = 64
|
69
|
-
# BITS = [64,63,61,60]
|
70
69
|
BITS = [64,4,3,1]
|
71
70
|
BITSELECT = BITS.map {|bit| "@reg[#{SIZE-bit}]"}.join("^")
|
72
71
|
|
data/lib/capricious/mwc5.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# capricious/mwc5.rb: 32-bit multiply-with-carry PRNG
|
2
2
|
#
|
3
|
-
# Copyright (c) 2010 Red Hat, Inc.
|
3
|
+
# Copyright:: Copyright (c) 2010 Red Hat, Inc.
|
4
|
+
# Author:: William Benton <willb@redhat.com>
|
5
|
+
# License:: http://www.apache.org/licenses/LICENSE-2.0
|
4
6
|
#
|
5
|
-
# Author: William Benton <willb@redhat.com>
|
6
7
|
# Algorithm due to George Marsaglia: http://groups.google.com/group/comp.lang.c/msg/e3c4ea1169e463ae
|
7
8
|
#
|
8
9
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -20,6 +21,7 @@
|
|
20
21
|
require 'capricious/lfsr'
|
21
22
|
|
22
23
|
module Capricious
|
24
|
+
# Multiply-with-carry pseudorandom number generator. Algorithm due to George Marsaglia.
|
23
25
|
class MWC5
|
24
26
|
attr_reader :seed, :seeds
|
25
27
|
def MWC5.new_with_seed(seed)
|
@@ -59,12 +61,9 @@ module Capricious
|
|
59
61
|
def shift_ks
|
60
62
|
# XXX: this is ugly, but it has to be to avoid coercing things into bignums
|
61
63
|
t=(@x^(@x>>7)) & 0xffffffff
|
62
|
-
@x
|
63
|
-
@
|
64
|
-
@
|
65
|
-
@w=@v
|
66
|
-
@v=(@v^(@v<<6))^(t^(t<<13)) & 0xffffffff
|
67
|
-
yy = ((@y & 0x7fffffff << 1) + 1) & 0xffffffff
|
64
|
+
@x,@y,@z,@w = @y,@z,@w,@v
|
65
|
+
@v=(@v^((@v&0x3ffffff)<<6))^(t^((t&0x1ffff)<<13)) & 0xffffffff
|
66
|
+
yy = (((@y & 0x7fffffff) << 1) + 1) & 0xffffffff
|
68
67
|
(yy * @v) & 0xffffffff;
|
69
68
|
end
|
70
69
|
end
|
data/lib/capricious/poisson.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# capricious/poisson.rb: Poisson-distribution PRNG, with selectable source-randomness policy
|
2
2
|
#
|
3
|
-
# Copyright (c) 2010 Red Hat, Inc.
|
4
|
-
#
|
5
|
-
#
|
3
|
+
# Copyright:: Copyright (c) 2010 Red Hat, Inc.
|
4
|
+
# Author:: William Benton <willb@redhat.com>
|
5
|
+
# License:: http://www.apache.org/licenses/LICENSE-2.0
|
6
6
|
#
|
7
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
8
|
# you may not use this file except in compliance with the License.
|
@@ -19,16 +19,27 @@
|
|
19
19
|
require 'capricious/generic_prng'
|
20
20
|
|
21
21
|
module Capricious
|
22
|
+
# Models a Poisson distribution
|
22
23
|
class Poisson
|
23
24
|
include PRNG
|
24
25
|
|
25
|
-
attr_reader :z
|
26
|
+
attr_reader :z, :expected_mean
|
26
27
|
|
28
|
+
# Initializes a new distribution. =l= is the lambda parameter (which is
|
29
|
+
# also the expected mean and variance); =seed=, =policy=, and =keep_stats=
|
30
|
+
# are as in =PRNG=. Note that the linear-feedback shift register policy
|
31
|
+
# will not provide acceptable results with this and other non-uniform
|
32
|
+
# distributions due to extremely high lag-k autocorrelation for small k.
|
27
33
|
def initialize(l, seed=nil, policy=MWC5, keep_stats=false)
|
28
34
|
@z = Math.exp(-l)
|
35
|
+
@expected_mean = l
|
29
36
|
prng_initialize(seed, policy, keep_stats)
|
30
37
|
end
|
31
38
|
|
39
|
+
def expected_variance
|
40
|
+
@expected_mean
|
41
|
+
end
|
42
|
+
|
32
43
|
private
|
33
44
|
# Algorithm 369, CACM, January 1970
|
34
45
|
def next_value
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# capricious/sample_sink.rb: sample aggregator
|
2
2
|
#
|
3
|
-
# Copyright (c) 2010 Red Hat, Inc.
|
4
|
-
#
|
5
|
-
#
|
3
|
+
# Copyright:: Copyright (c) 2010 Red Hat, Inc.
|
4
|
+
# Author:: William Benton <willb@redhat.com>
|
5
|
+
# License:: http://www.apache.org/licenses/LICENSE-2.0
|
6
6
|
#
|
7
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
8
|
# you may not use this file except in compliance with the License.
|
@@ -17,6 +17,8 @@
|
|
17
17
|
# limitations under the License.
|
18
18
|
|
19
19
|
module Capricious
|
20
|
+
|
21
|
+
# Records aggregate data about a stream of samples in constant space.
|
20
22
|
class SampleSink
|
21
23
|
|
22
24
|
attr_reader :min, :max, :count, :mean, :variance
|
@@ -30,17 +32,22 @@ module Capricious
|
|
30
32
|
@sum_x2 = 0.0
|
31
33
|
end
|
32
34
|
|
35
|
+
# Adds a sample and updates =min=, =max= and =count= as well as =mean=,
|
36
|
+
# and =variance= estimates.
|
33
37
|
def put(sample)
|
34
38
|
update_stats(sample)
|
35
39
|
update_estimates(sample)
|
36
40
|
nil
|
37
41
|
end
|
38
42
|
|
43
|
+
# Adds a sample and updates =min=, =max= and =count= as well as =mean=,
|
44
|
+
# and =variance= estimates.
|
39
45
|
def <<(sample)
|
40
46
|
self.put(sample)
|
41
47
|
self
|
42
48
|
end
|
43
49
|
|
50
|
+
# Returns the square root of the variance for all witnessed samples.
|
44
51
|
def stddev
|
45
52
|
Math::sqrt(@variance)
|
46
53
|
end
|
data/lib/capricious/uniform.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# capricious/uniform.rb: uniform-distribution PRNG, with selectable source-randomness policy
|
2
2
|
#
|
3
|
-
# Copyright (c) 2010 Red Hat, Inc.
|
4
|
-
#
|
5
|
-
#
|
3
|
+
# Copyright:: Copyright (c) 2010 Red Hat, Inc.
|
4
|
+
# Author:: William Benton <willb@redhat.com>
|
5
|
+
# License:: http://www.apache.org/licenses/LICENSE-2.0
|
6
6
|
#
|
7
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
8
|
# you may not use this file except in compliance with the License.
|
@@ -19,10 +19,32 @@
|
|
19
19
|
require 'capricious/generic_prng'
|
20
20
|
|
21
21
|
module Capricious
|
22
|
+
|
23
|
+
# Creates pseudorandom numbers in the range [0,1) that satisfy a uniform distribution.
|
22
24
|
class Uniform
|
23
25
|
include PRNG
|
26
|
+
UNIFORM_MIN = 0.0
|
27
|
+
UNIFORM_MAX = 1.0
|
28
|
+
|
29
|
+
# Returns the expected mean for this distribution: =(min + max) / 2=.
|
30
|
+
def expected_mean
|
31
|
+
(min + max) / 2
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns the expected variance for this distribution: =(max - min) ** 2 / 12=.
|
35
|
+
def expected_variance
|
36
|
+
((max - min) ** 2) / 12
|
37
|
+
end
|
24
38
|
|
25
39
|
private
|
40
|
+
def min
|
41
|
+
@min || UNIFORM_MIN
|
42
|
+
end
|
43
|
+
|
44
|
+
def max
|
45
|
+
@max || UNIFORM_MAX
|
46
|
+
end
|
47
|
+
|
26
48
|
def next_value
|
27
49
|
@prng.next_f
|
28
50
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
module Capricious
|
4
|
+
SAMPLE_COUNT = 60000
|
5
|
+
|
6
|
+
describe BiasedUniform do
|
7
|
+
MIN = 13.37
|
8
|
+
MAX = 14.53
|
9
|
+
|
10
|
+
def generate_samples(policy=MWC5, count=SAMPLE_COUNT)
|
11
|
+
@uniform = Capricious::BiasedUniform.new(MIN, MAX, nil, policy, true)
|
12
|
+
count.times {@uniform.next}
|
13
|
+
end
|
14
|
+
|
15
|
+
[LFSR,MWC5].each do |policy|
|
16
|
+
it "should, given policy #{policy.name}, generate numbers in the range (#{MIN},#{MAX}]" do
|
17
|
+
generate_samples(policy)
|
18
|
+
@uniform.aggregate.max.should <= MAX
|
19
|
+
@uniform.aggregate.min.should > MIN
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should, given policy #{policy.name}, generate uniformly-distributed numbers in the range (#{MIN},#{MAX}], as judged by mean and variance estimates" do
|
23
|
+
generate_samples(policy)
|
24
|
+
@uniform.aggregate.mean.should be_close(@uniform.expected_mean, 0.01)
|
25
|
+
@uniform.aggregate.stddev.should be_close(Math.sqrt(@uniform.expected_variance), 0.01)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should, given policy #{policy.name}, generate the same sequence given the same seed" do
|
29
|
+
@uniform = BiasedUniform.new(MIN, MAX, nil, policy, false)
|
30
|
+
@uniform2 = BiasedUniform.new(MIN, MAX, nil, policy, false)
|
31
|
+
(SAMPLE_COUNT/40).times { @uniform2.next.should == @uniform.next }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/spec/erlang_spec.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
module Capricious
|
4
|
+
LAMBDA = 3
|
5
|
+
R = 6
|
6
|
+
SAMPLE_COUNT = 200
|
7
|
+
|
8
|
+
describe Erlang do
|
9
|
+
def generate_samples(count=SAMPLE_COUNT)
|
10
|
+
count.times {@erlang.next}
|
11
|
+
end
|
12
|
+
|
13
|
+
before(:each) do
|
14
|
+
@erlang = Capricious::Erlang.new(LAMBDA, R, nil, MWC5, true)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should generate distributed numbers in an Erlang distribution with lambda #{LAMBDA} and r #{R}, as judged by mean and variance estimates" do
|
18
|
+
generate_samples(10000)
|
19
|
+
|
20
|
+
@erlang.aggregate.mean.should be_close(@erlang.expected_mean, 0.05)
|
21
|
+
@erlang.aggregate.variance.should be_close(@erlang.expected_variance, 0.15)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should generate the same sequence given the same seed" do
|
25
|
+
@erlang2 = Erlang.new(LAMBDA, R, @erlang.seed, MWC5, true)
|
26
|
+
SAMPLE_COUNT.times { @erlang2.next.should == @erlang.next }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
module Capricious
|
4
|
+
LAMBDA = 8
|
5
|
+
SAMPLE_COUNT = 200
|
6
|
+
|
7
|
+
describe Exponential do
|
8
|
+
def generate_samples(count=SAMPLE_COUNT)
|
9
|
+
count.times {@expo.next}
|
10
|
+
end
|
11
|
+
|
12
|
+
before(:each) do
|
13
|
+
@expo = Capricious::Exponential.new(LAMBDA, nil, MWC5, true)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should generate distributed numbers in an exponential distribution with lambda #{LAMBDA}, as judged by mean and variance estimates" do
|
17
|
+
generate_samples(10000)
|
18
|
+
|
19
|
+
@expo.aggregate.mean.should be_close(@expo.expected_mean, 0.05)
|
20
|
+
@expo.aggregate.variance.should be_close(@expo.expected_variance, 0.15)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should generate the same sequence given the same seed" do
|
24
|
+
@expo2 = Exponential.new(LAMBDA, @expo.seed, MWC5, true)
|
25
|
+
SAMPLE_COUNT.times { @expo2.next.should == @expo.next }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/spec/uniform_spec.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
3
|
module Capricious
|
4
|
-
EXPECTED_MEAN = 0.5
|
5
|
-
EXPECTED_STDDEV = 0.288675134594813
|
6
4
|
SAMPLE_COUNT = 20000
|
7
5
|
|
8
6
|
describe Uniform do
|
@@ -20,8 +18,8 @@ module Capricious
|
|
20
18
|
|
21
19
|
it "should, given policy #{policy.name}, generate uniformly-distributed numbers in the range (0,1], as judged by mean and variance estimates" do
|
22
20
|
generate_samples(policy)
|
23
|
-
@uniform.aggregate.mean.should be_close(
|
24
|
-
@uniform.aggregate.stddev.should be_close(
|
21
|
+
@uniform.aggregate.mean.should be_close(@uniform.expected_mean, 0.01)
|
22
|
+
@uniform.aggregate.stddev.should be_close(Math.sqrt(@uniform.expected_variance), 0.01)
|
25
23
|
end
|
26
24
|
|
27
25
|
it "should, given policy #{policy.name}, generate the same sequence given the same seed" do
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capricious
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 2
|
8
|
+
- 1
|
9
|
+
version: 0.2.1
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Will Benton
|
@@ -9,19 +14,23 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date: 2010-03-
|
17
|
+
date: 2010-03-15 00:00:00 -05:00
|
13
18
|
default_executable:
|
14
19
|
dependencies:
|
15
20
|
- !ruby/object:Gem::Dependency
|
16
21
|
name: rspec
|
17
|
-
|
18
|
-
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
24
|
requirements:
|
21
25
|
- - ">="
|
22
26
|
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 1
|
29
|
+
- 2
|
30
|
+
- 9
|
23
31
|
version: 1.2.9
|
24
|
-
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id001
|
25
34
|
description: Pseudorandom number generator classes and support code, parameterized on a source of randomness and a probability distribution
|
26
35
|
email: willb@redhat.com
|
27
36
|
executables: []
|
@@ -40,12 +49,18 @@ files:
|
|
40
49
|
- Rakefile
|
41
50
|
- VERSION
|
42
51
|
- lib/capricious.rb
|
52
|
+
- lib/capricious/biased_uniform.rb
|
53
|
+
- lib/capricious/erlang.rb
|
54
|
+
- lib/capricious/exponential.rb
|
43
55
|
- lib/capricious/generic_prng.rb
|
44
56
|
- lib/capricious/lfsr.rb
|
45
57
|
- lib/capricious/mwc5.rb
|
46
58
|
- lib/capricious/poisson.rb
|
47
59
|
- lib/capricious/sample_sink.rb
|
48
60
|
- lib/capricious/uniform.rb
|
61
|
+
- spec/biased_uniform_spec.rb
|
62
|
+
- spec/erlang_spec.rb
|
63
|
+
- spec/exponential_spec.rb
|
49
64
|
- spec/poisson_spec.rb
|
50
65
|
- spec/spec.opts
|
51
66
|
- spec/spec_helper.rb
|
@@ -63,22 +78,27 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
63
78
|
requirements:
|
64
79
|
- - ">="
|
65
80
|
- !ruby/object:Gem::Version
|
81
|
+
segments:
|
82
|
+
- 0
|
66
83
|
version: "0"
|
67
|
-
version:
|
68
84
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
85
|
requirements:
|
70
86
|
- - ">="
|
71
87
|
- !ruby/object:Gem::Version
|
88
|
+
segments:
|
89
|
+
- 0
|
72
90
|
version: "0"
|
73
|
-
version:
|
74
91
|
requirements: []
|
75
92
|
|
76
93
|
rubyforge_project:
|
77
|
-
rubygems_version: 1.3.
|
94
|
+
rubygems_version: 1.3.6
|
78
95
|
signing_key:
|
79
96
|
specification_version: 3
|
80
97
|
summary: Pseudorandom number generator classes and support code
|
81
98
|
test_files:
|
99
|
+
- spec/biased_uniform_spec.rb
|
100
|
+
- spec/erlang_spec.rb
|
101
|
+
- spec/exponential_spec.rb
|
82
102
|
- spec/poisson_spec.rb
|
83
103
|
- spec/spec_helper.rb
|
84
104
|
- spec/uniform_spec.rb
|