capricious 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +5 -1
- data/VERSION +1 -1
- data/lib/capricious.rb +1 -0
- data/lib/capricious/normal.rb +59 -0
- data/spec/normal_spec.rb +34 -0
- metadata +5 -2
data/CHANGES
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.2
|
data/lib/capricious.rb
CHANGED
@@ -0,0 +1,59 @@
|
|
1
|
+
# capricious/normal.rb: Normal 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
|
+
# Normal-distribution PRNG, uses polar form of Box-Muller transform.
|
23
|
+
class Normal
|
24
|
+
include PRNG
|
25
|
+
|
26
|
+
attr_reader :expected_mean, :expected_variance
|
27
|
+
|
28
|
+
# Initializes a new distribution. mean and variance are the distribution parameters; =seed=,
|
29
|
+
# =policy=, and =keep_stats= are as in =PRNG=.
|
30
|
+
def initialize(mean, variance, seed=nil, policy=MWC5, keep_stats=false)
|
31
|
+
@expected_mean = mean.to_f
|
32
|
+
@expected_variance = variance.to_f
|
33
|
+
@stddev = Math.sqrt(@expected_variance)
|
34
|
+
@values = []
|
35
|
+
prng_initialize(seed, policy, keep_stats)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
def next_value
|
40
|
+
return @values.pop if @values.size() > 0
|
41
|
+
u, v, r = 0, 0, 0
|
42
|
+
|
43
|
+
begin
|
44
|
+
u = 2 * @prng.next_f - 1
|
45
|
+
v = 2 * @prng.next_f - 1
|
46
|
+
r = u ** 2 + v ** 2
|
47
|
+
end while r == 0 || r > 1
|
48
|
+
|
49
|
+
c = Math.sqrt(-2 * Math.log(r) / r)
|
50
|
+
|
51
|
+
@values << scale(v * c)
|
52
|
+
scale(u * c)
|
53
|
+
end
|
54
|
+
|
55
|
+
def scale(val)
|
56
|
+
@expected_mean + (val * @stddev)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/spec/normal_spec.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
module Capricious
|
4
|
+
SAMPLE_COUNT = 30000
|
5
|
+
|
6
|
+
describe Normal do
|
7
|
+
def generate_samples(policy, mean, variance, count=SAMPLE_COUNT)
|
8
|
+
@normal = Capricious::Normal.new(mean, variance, nil, policy, true)
|
9
|
+
count.times {@normal.next}
|
10
|
+
end
|
11
|
+
|
12
|
+
[LFSR,MWC5].each do |policy|
|
13
|
+
[[0.0,1.0], [10.0,3.5]].each do |mean, variance|
|
14
|
+
|
15
|
+
it "should, given policy #{policy.name}, generate normally-distributed numbers with a mean of #{mean} and a variance of #{variance}, as judged by mean estimates" do
|
16
|
+
generate_samples(policy, mean, variance)
|
17
|
+
@normal.aggregate.mean.should be_close(@normal.expected_mean, 0.01 * [mean, 1.0].max)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should, given policy #{policy.name}, generate normally-distributed numbers with a mean of #{mean} and a variance of #{variance}, as judged by variance estimates" do
|
21
|
+
generate_samples(policy, mean, variance)
|
22
|
+
@normal.aggregate.stddev.should be_close(Math.sqrt(@normal.expected_variance), 0.075 * variance)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should, given policy #{policy.name}, generate the same sequence given the same seed" do
|
27
|
+
@normal = Normal.new(0.0, 1.0, nil, policy, false)
|
28
|
+
@normal2 = Normal.new(0.0, 1.0, nil, policy, false)
|
29
|
+
(SAMPLE_COUNT/10).times { @normal2.next.should == @normal.next }
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
version: 0.2.
|
8
|
+
- 2
|
9
|
+
version: 0.2.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Will Benton
|
@@ -55,12 +55,14 @@ files:
|
|
55
55
|
- lib/capricious/generic_prng.rb
|
56
56
|
- lib/capricious/lfsr.rb
|
57
57
|
- lib/capricious/mwc5.rb
|
58
|
+
- lib/capricious/normal.rb
|
58
59
|
- lib/capricious/poisson.rb
|
59
60
|
- lib/capricious/sample_sink.rb
|
60
61
|
- lib/capricious/uniform.rb
|
61
62
|
- spec/biased_uniform_spec.rb
|
62
63
|
- spec/erlang_spec.rb
|
63
64
|
- spec/exponential_spec.rb
|
65
|
+
- spec/normal_spec.rb
|
64
66
|
- spec/poisson_spec.rb
|
65
67
|
- spec/spec.opts
|
66
68
|
- spec/spec_helper.rb
|
@@ -99,6 +101,7 @@ test_files:
|
|
99
101
|
- spec/biased_uniform_spec.rb
|
100
102
|
- spec/erlang_spec.rb
|
101
103
|
- spec/exponential_spec.rb
|
104
|
+
- spec/normal_spec.rb
|
102
105
|
- spec/poisson_spec.rb
|
103
106
|
- spec/spec_helper.rb
|
104
107
|
- spec/uniform_spec.rb
|