fibonacci_rng 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/README.md +5 -1
- data/docs/Chi Squared.ods +0 -0
- data/docs/Fib_Scatter.png +0 -0
- data/docs/fib corr.png +0 -0
- data/docs/int corr.png +0 -0
- data/docs/scatter.ods +0 -0
- data/docs/scatter_fib.txt +8193 -0
- data/docs/scatter_int.txt +8193 -0
- data/lib/fibonacci_rng/version.rb +1 -1
- data/lib/fibonacci_rng.rb +47 -6
- data/prng.rb +5 -2
- data/tests/fibinacci_rng_tests.rb +29 -4
- data/tools/scatter_plot.rb +26 -0
- metadata +10 -2
data/lib/fibonacci_rng.rb
CHANGED
@@ -9,10 +9,26 @@ class FibonacciRng
|
|
9
9
|
@tickle = '0'
|
10
10
|
|
11
11
|
#Create the default seed string.
|
12
|
-
def self.
|
12
|
+
def self.new_seed
|
13
13
|
Time.now.to_s + @tickle.succ!
|
14
14
|
end
|
15
15
|
|
16
|
+
#Get a random number from the class based generator. This exists only
|
17
|
+
#for compatibility purposes. It is far better to create instances of
|
18
|
+
#generators than to use a shared, global one.
|
19
|
+
def self.rand(max=0)
|
20
|
+
(@hidden ||= FibonacciRng.new).rand(max)
|
21
|
+
end
|
22
|
+
|
23
|
+
#Initialize the class based generator. This exists only
|
24
|
+
#for compatibility purposes. It is far better to create instances of
|
25
|
+
#generators than to use a shared, global one.
|
26
|
+
def self.srand(seed=FibonacciRng.new_seed, depth=8)
|
27
|
+
old = (@hidden && @hidden.seed)
|
28
|
+
@hidden = FibonacciRng.new(seed, depth)
|
29
|
+
old
|
30
|
+
end
|
31
|
+
|
16
32
|
CHOP = 0x1FFFFFFF
|
17
33
|
BYTE = 0xFF
|
18
34
|
WORD = 0xFFFF
|
@@ -21,30 +37,48 @@ class FibonacciRng
|
|
21
37
|
#An accessor for the depth!
|
22
38
|
attr_reader :depth
|
23
39
|
|
40
|
+
#An accessor for the seed value!
|
41
|
+
attr_reader :seed
|
42
|
+
|
24
43
|
#Initialize the PRN generator
|
25
|
-
def initialize(
|
44
|
+
def initialize(seed=FibonacciRng.new_seed, depth=8)
|
26
45
|
fail "Invalid depth value (3..30)." unless (3..30) === depth
|
27
46
|
@depth = depth
|
28
|
-
|
47
|
+
srand(seed)
|
29
48
|
end
|
30
49
|
|
31
50
|
#Set up a new seed value
|
32
|
-
def
|
51
|
+
def srand(seed=FibonacciRng.new_seed)
|
52
|
+
@seed = seed
|
33
53
|
@buffer = Array.new(@depth+2, 0)
|
34
54
|
seedsrc = (seed.to_s + seed.class.to_s + 'Leonardo Pisano').each_byte.cycle
|
35
55
|
indxsrc = (0...depth).cycle
|
36
56
|
do_reseed(indxsrc, seedsrc)
|
37
57
|
end
|
38
58
|
|
59
|
+
#A (mostly) compatible access point for random numbers.
|
60
|
+
def rand(max=0)
|
61
|
+
@hidden ||= FibonacciRng.new
|
62
|
+
|
63
|
+
if max.is_a?(Range)
|
64
|
+
min = max.min
|
65
|
+
@hidden.dice(1 + max.max - min) + min
|
66
|
+
elsif max == 0
|
67
|
+
@hidden.float
|
68
|
+
else
|
69
|
+
@hidden.dice(max.to_i)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
39
73
|
#Roll a dice.
|
40
74
|
def dice(sides)
|
41
75
|
limit = ((CHOP+1) / sides) * sides
|
42
76
|
|
43
77
|
begin
|
44
78
|
do_spin
|
45
|
-
end until @buffer[0] < limit
|
79
|
+
end until (value = @buffer[0]) < limit
|
46
80
|
|
47
|
-
|
81
|
+
value % sides
|
48
82
|
end
|
49
83
|
|
50
84
|
#Get a pseudo random byte
|
@@ -53,6 +87,13 @@ class FibonacciRng
|
|
53
87
|
@buffer[0] & BYTE
|
54
88
|
end
|
55
89
|
|
90
|
+
#Get a string of random bytes
|
91
|
+
def bytes(length)
|
92
|
+
result = ""
|
93
|
+
length.times {result << byte.chr}
|
94
|
+
result
|
95
|
+
end
|
96
|
+
|
56
97
|
#Get a pseudo random word
|
57
98
|
def word
|
58
99
|
do_spin
|
data/prng.rb
CHANGED
@@ -21,7 +21,7 @@ module PrngTestSuite
|
|
21
21
|
puts "Where:"
|
22
22
|
puts " <locn> fib code location, either 'gem' or 'local'"
|
23
23
|
puts " <gen> select a generator, either 'fib' or 'int'"
|
24
|
-
puts " <test> select a test, either 'chisq' or '
|
24
|
+
puts " <test> select a test, either 'chisq', 'auto', or 'scatter'"
|
25
25
|
puts " <max> the number of bins to test (2..65535)"
|
26
26
|
puts " <count> the number of samples to test (1..1000000)"
|
27
27
|
puts
|
@@ -44,6 +44,7 @@ end
|
|
44
44
|
require_relative 'tools/internal_rng'
|
45
45
|
require_relative 'tools/chi_squared'
|
46
46
|
require_relative 'tools/auto_corr'
|
47
|
+
require_relative 'tools/scatter_plot'
|
47
48
|
|
48
49
|
module PrngTestSuite
|
49
50
|
|
@@ -60,11 +61,13 @@ module PrngTestSuite
|
|
60
61
|
tester = ChiSquaredTest.new
|
61
62
|
elsif ARGV[2] == 'auto'
|
62
63
|
tester = AutoCorrelator.new
|
64
|
+
elsif ARGV[2] == 'scatter'
|
65
|
+
tester = ScatterPlot.new
|
63
66
|
else
|
64
67
|
PrngTestSuite.usage "Error: missing or invalid test parameter."
|
65
68
|
end
|
66
69
|
|
67
|
-
unless (2..
|
70
|
+
unless (2..65536) === (max = ARGV[3].to_i)
|
68
71
|
PrngTestSuite.usage "Error: missing or invalid max parameter."
|
69
72
|
end
|
70
73
|
|
@@ -41,7 +41,6 @@ class CoreTester < MiniTest::Unit::TestCase
|
|
41
41
|
100.times do
|
42
42
|
assert((0...65536) === prng.word)
|
43
43
|
end
|
44
|
-
|
45
44
|
end
|
46
45
|
|
47
46
|
def test_that_it_creates_floats
|
@@ -51,7 +50,34 @@ class CoreTester < MiniTest::Unit::TestCase
|
|
51
50
|
value = prng.float
|
52
51
|
assert((value >= 0.0) && (value < 1.0))
|
53
52
|
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_compatible_global_dice_rolls
|
56
|
+
100.times do
|
57
|
+
assert((0...6) === FibonacciRng.rand(6))
|
58
|
+
end
|
59
|
+
end
|
54
60
|
|
61
|
+
def test_compatible_global_dice_rolls_range
|
62
|
+
100.times do
|
63
|
+
assert((0...6) === FibonacciRng.rand(0...6))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_compatible_global_floats
|
68
|
+
100.times do
|
69
|
+
value = FibonacciRng.rand(0)
|
70
|
+
assert((value >= 0.0) && (value < 1.0))
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_random_string
|
75
|
+
prng = FibonacciRng.new
|
76
|
+
|
77
|
+
rs = prng.bytes(10)
|
78
|
+
|
79
|
+
assert(rs.is_a?(String))
|
80
|
+
assert_equal(10, rs.length)
|
55
81
|
end
|
56
82
|
|
57
83
|
def test_that_it_makes_unique_sequnces
|
@@ -70,8 +96,8 @@ class CoreTester < MiniTest::Unit::TestCase
|
|
70
96
|
end
|
71
97
|
|
72
98
|
def test_that_it_makes_repeatable_sequnces
|
73
|
-
prnga = FibonacciRng.new(
|
74
|
-
prngb = FibonacciRng.new(
|
99
|
+
prnga = FibonacciRng.new(0)
|
100
|
+
prngb = FibonacciRng.new(0)
|
75
101
|
|
76
102
|
buffa = []
|
77
103
|
buffb = []
|
@@ -83,5 +109,4 @@ class CoreTester < MiniTest::Unit::TestCase
|
|
83
109
|
|
84
110
|
assert(buffa == buffb)
|
85
111
|
end
|
86
|
-
|
87
112
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
#A Chi Squared tester
|
4
|
+
class ScatterPlot
|
5
|
+
|
6
|
+
#Run a chi squared test on the random number generator.
|
7
|
+
def run(gen, max, count)
|
8
|
+
puts "Starting test"
|
9
|
+
bins = Array.new(max * 2, 0)
|
10
|
+
|
11
|
+
|
12
|
+
count.times do |i|
|
13
|
+
bins[i] = [gen.dice(max)]
|
14
|
+
end
|
15
|
+
|
16
|
+
count.times do |i|
|
17
|
+
bins[i] << gen.dice(max)
|
18
|
+
end
|
19
|
+
|
20
|
+
count.times do |i|
|
21
|
+
puts "#{bins[i][0]}, #{bins[i][1]}"
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fibonacci_rng
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Camilleri
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-11-
|
11
|
+
date: 2014-11-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -79,6 +79,13 @@ files:
|
|
79
79
|
- LICENSE.txt
|
80
80
|
- README.md
|
81
81
|
- Rakefile
|
82
|
+
- docs/Chi Squared.ods
|
83
|
+
- docs/Fib_Scatter.png
|
84
|
+
- docs/fib corr.png
|
85
|
+
- docs/int corr.png
|
86
|
+
- docs/scatter.ods
|
87
|
+
- docs/scatter_fib.txt
|
88
|
+
- docs/scatter_int.txt
|
82
89
|
- fibonacci_rng.gemspec
|
83
90
|
- lib/fibonacci_rng.rb
|
84
91
|
- lib/fibonacci_rng/version.rb
|
@@ -88,6 +95,7 @@ files:
|
|
88
95
|
- tools/auto_corr.rb
|
89
96
|
- tools/chi_squared.rb
|
90
97
|
- tools/internal_rng.rb
|
98
|
+
- tools/scatter_plot.rb
|
91
99
|
homepage: ''
|
92
100
|
licenses:
|
93
101
|
- MIT
|