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