fibonacci_rng 0.0.4 → 0.0.5

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.
@@ -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