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.
@@ -2,5 +2,5 @@
2
2
 
3
3
  #The class of Fibonacci inspired random number generators.
4
4
  class FibonacciRng
5
- VERSION = "0.0.4"
5
+ VERSION = "0.0.5"
6
6
  end
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.seed
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(depth=8, seed=FibonacciRng.seed)
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
- reseed(seed)
47
+ srand(seed)
29
48
  end
30
49
 
31
50
  #Set up a new seed value
32
- def reseed(seed=FibonacciRng.seed)
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
- @buffer[0] % sides
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 'auto'"
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..65535) === (max = ARGV[3].to_i)
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(8, 0)
74
- prngb = FibonacciRng.new(8, 0)
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
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-16 00:00:00.000000000 Z
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