random 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,25 @@
1
+ require 'test/unit'
2
+
3
+ require 'math/statistics/chi_square'
4
+
5
+ class TestChiSquare < Test::Unit::TestCase
6
+ def test_01_ensure_proper_parsing_of_file
7
+ assert_equal(nil, Math::Statistics.critical_chi_square_value(1, 0.995))
8
+ assert_equal(nil, Math::Statistics.critical_chi_square_value(1, 0.99))
9
+ assert_equal(0.001, Math::Statistics.critical_chi_square_value(1, 0.975))
10
+ assert_equal(6.635, Math::Statistics.critical_chi_square_value(1, 0.01))
11
+ assert_equal(7.879, Math::Statistics.critical_chi_square_value(1, 0.005))
12
+
13
+ assert_equal(0.010, Math::Statistics.critical_chi_square_value(2, 0.995))
14
+ assert_equal(0.020, Math::Statistics.critical_chi_square_value(2, 0.99))
15
+ assert_equal(5.991, Math::Statistics.critical_chi_square_value(2, 0.05))
16
+ assert_equal(10.597, Math::Statistics.critical_chi_square_value(2, 0.005))
17
+
18
+ assert_equal(8.907, Math::Statistics.critical_chi_square_value(19, 0.975))
19
+ assert_equal(38.582, Math::Statistics.critical_chi_square_value(19, 0.005))
20
+
21
+ assert_equal(104.215, Math::Statistics.critical_chi_square_value(70, 0.005))
22
+
23
+ assert_equal(67.328, Math::Statistics.critical_chi_square_value(100, 0.995))
24
+ end
25
+ end
@@ -0,0 +1,131 @@
1
+ require 'test/unit'
2
+
3
+ require 'random'
4
+ include Random
5
+
6
+ class TestMersenneTwister < Test::Unit::TestCase
7
+ NumReps = 30
8
+ NumSmallReps = NumReps / 10
9
+
10
+ def test_01_initialize
11
+ mt1 = MersenneTwister.new
12
+ assert_kind_of(Random::MersenneTwister, mt)
13
+ assert_equal(0, mt.min)
14
+ assert_equal(-1 + 2**32, mt.max)
15
+
16
+ # Lets just check that we do not get the same value multiple times
17
+ # (which happens if the state has not been initialized for example)
18
+ first_10 = Array.new(10).map {mt1.next}
19
+ assert(10 == first_10.uniq.length,
20
+ "First 10 generated nums: #{first_10.inspect}")
21
+ end
22
+
23
+ def setup
24
+ @mt = MersenneTwister.new(rand(1e4))
25
+ end
26
+
27
+ # Default test object
28
+ def mt; @mt; end
29
+
30
+ def test_02_rand_int_limited
31
+ NumSmallReps.times do
32
+ assert_chi_square {mt.rand_int_limited(10)}
33
+ end
34
+ end
35
+
36
+ def take_next(num, rng)
37
+ Array.new(num).map {rng.next}
38
+ end
39
+
40
+ def assert_next(num, mt1, mt2)
41
+ assert_equal(take_next(num, mt1), take_next(num, mt2))
42
+ end
43
+
44
+ def test_03_same_seed_gives_same_sequence
45
+ NumReps.times do
46
+ seed = rand(1e6)
47
+ mt1, mt2 = MersenneTwister.new(seed), MersenneTwister.new(seed)
48
+ assert_next(1000, mt1, mt2)
49
+ end
50
+ end
51
+
52
+ def test_04_different_seed_gives_different_sequence
53
+ NumReps.times do
54
+ seed = rand(1e6)
55
+ mt1 = MersenneTwister.new(seed)
56
+ mt2 = MersenneTwister.new(seed+1+rand(1e3))
57
+ assert(take_next(100, mt1) != take_next(100, mt2))
58
+ end
59
+ end
60
+
61
+ def test_05_rand_float
62
+ NumSmallReps.times do
63
+ assert_chi_square {(10.0 * mt.rand_float).floor}
64
+ end
65
+ end
66
+
67
+ def test_06_rand_without_arg
68
+ NumSmallReps.times do
69
+ assert_chi_square do
70
+ rv = mt.rand()
71
+ assert_kind_of(Float, rv)
72
+ (10.0 * rv).floor
73
+ end
74
+ end
75
+ end
76
+
77
+ def test_07_rand_with_small_int_arg
78
+ NumSmallReps.times do
79
+ df = Math::Statistics.valid_degrees_of_freedom.random_element
80
+ limit = df + 1
81
+ assert_chi_square do
82
+ rv = mt.rand(limit)
83
+ assert(rv.kind_of?(Fixnum) && rv >= 0 && rv < limit)
84
+ rv
85
+ end
86
+ end
87
+ end
88
+
89
+ def test_08_state
90
+ NumReps.times do
91
+ s = mt.state
92
+ assert_kind_of(Array, s)
93
+ assert_equal(624+1, s.length)
94
+ s.each {|e| assert(Integer === e)}
95
+ end
96
+ end
97
+
98
+ def test_09_state_set
99
+ NumReps.times do
100
+ mt1 = MersenneTwister.new(rand(1e6))
101
+ state_taken_at = rand(1e3)
102
+ state_taken_at.times {mt1.next}
103
+ state = mt1.state
104
+ assert_kind_of(Array, state)
105
+ assert_equal(624+1, state.length)
106
+ mt2 = MersenneTwister.new(rand(1e6))
107
+ mt2.state = state
108
+ assert_equal(mt1.state, mt2.state)
109
+ assert_equal(state, mt1.state)
110
+ assert_next(1000, mt1, mt2)
111
+ end
112
+ end
113
+
114
+ def test_10_marshaling
115
+ NumReps.times do
116
+ mt1 = MersenneTwister.new(rand(1e6))
117
+ state_taken_at = rand(1e3)
118
+ state_taken_at.times {mt1.next}
119
+ mstr1 = Marshal.dump(mt1)
120
+ mt2 = Marshal.load(mstr1)
121
+ assert_next(1000, mt1, mt2)
122
+ assert_equal(Marshal.dump(mt1), Marshal.dump(mt2))
123
+ end
124
+ end
125
+
126
+ def test_11_rand
127
+ assert_rand(mt)
128
+ assert_chi_square {mt.rand(2)}
129
+ assert_chi_square_floats {mt.rand}
130
+ end
131
+ end
@@ -0,0 +1,168 @@
1
+ require 'test/unit'
2
+
3
+ require 'random/random_number_generator'
4
+ include Random
5
+
6
+ # Mock sub-class that implements next simply by taking values from an array.
7
+ class MockRNG < Random::RandomNumberGenerator
8
+ def initialize(*values)
9
+ @values, @len = values, values.length
10
+ @index = 0
11
+ end
12
+
13
+ def next
14
+ n = @values[@index]
15
+ @index = (@index + 1) % @len
16
+ n
17
+ end
18
+
19
+ def marshal_dump; [@values, @index]; end
20
+ def marshal_load(ary)
21
+ @values, @index = ary
22
+ @len = @values.length
23
+ end
24
+
25
+ # Lift protected methods so we can test them
26
+ public :calc_mask, :mask, :num_bits_to_represent, :mask_for_int, :add_bits
27
+ end
28
+
29
+ class TestRandomNumberGenerator < Test::Unit::TestCase
30
+ NumReps = 30
31
+ NumSmallReps = NumReps / 10
32
+
33
+ attr_reader :rng
34
+
35
+ def setup
36
+ @rng = MockRNG.new(*(0..1000))
37
+ end
38
+
39
+ def test_01_initialize
40
+ assert_kind_of(MockRNG, rng)
41
+ assert_equal(0, rng.min)
42
+ assert_equal(2**32-1, rng.max)
43
+ assert_equal(32, rng.num_random_bits)
44
+ assert_equal(4, rng.num_random_bytes)
45
+ end
46
+
47
+ def test_02_calc_mask
48
+ assert_equal(0b0000, rng.calc_mask(0))
49
+ assert_equal(0b0001, rng.calc_mask(1))
50
+ assert_equal(0b0011, rng.calc_mask(2))
51
+ assert_equal(0b0111, rng.calc_mask(3))
52
+ assert_equal(0b1111, rng.calc_mask(4))
53
+ assert_equal(0x1f, rng.calc_mask(5))
54
+ assert_equal(0x3f, rng.calc_mask(6))
55
+ assert_equal(0x7f, rng.calc_mask(7))
56
+ assert_equal(0xff, rng.calc_mask(8))
57
+ (9..65).each {|i| assert_equal(2**i - 1, rng.calc_mask(i))}
58
+ assert_equal(2**1000 - 1, rng.calc_mask(1000))
59
+ end
60
+
61
+ def test_03_mask
62
+ assert_equal(0b0000, rng.mask(0))
63
+ assert_equal(0b0001, rng.mask(1))
64
+ assert_equal(0b0011, rng.mask(2))
65
+ assert_equal(0b0111, rng.mask(3))
66
+ assert_equal(0b1111, rng.mask(4))
67
+ assert_equal(0x1f, rng.mask(5))
68
+ assert_equal(0x3f, rng.mask(6))
69
+ assert_equal(0x7f, rng.mask(7))
70
+ assert_equal(0xff, rng.mask(8))
71
+ (9..65).each {|i| assert_equal(2**i - 1, rng.mask(i))}
72
+ assert_equal(2**1000 - 1, rng.mask(1000))
73
+ end
74
+
75
+ def test_04_num_bits
76
+ (0..1).each {|i| assert_equal(1, rng.num_bits_to_represent(i))}
77
+ (2..3).each {|i| assert_equal(2, rng.num_bits_to_represent(i))}
78
+ (4..7).each {|i| assert_equal(3, rng.num_bits_to_represent(i))}
79
+ (8..15).each {|i| assert_equal(4, rng.num_bits_to_represent(i))}
80
+ (16..31).each {|i| assert_equal(5, rng.num_bits_to_represent(i))}
81
+ (32..63).each {|i| assert_equal(6, rng.num_bits_to_represent(i))}
82
+ assert_equal(7, rng.num_bits_to_represent(64))
83
+ assert_equal(8, rng.num_bits_to_represent(128))
84
+ assert_equal(1023, rng.num_bits_to_represent(2**1023-1))
85
+ assert_equal(1024, rng.num_bits_to_represent(2**1023))
86
+ assert_equal(1025, rng.num_bits_to_represent(2**1024))
87
+ assert_equal(2048, rng.num_bits_to_represent(2**2048-1))
88
+ assert_equal(2049, rng.num_bits_to_represent(2**2048))
89
+ end
90
+
91
+ def test_05_mask_for_int
92
+ assert_equal(0x0001, rng.mask_for_int(0))
93
+ assert_equal(0x0001, rng.mask_for_int(1))
94
+ assert_equal(0x0003, rng.mask_for_int(2))
95
+ assert_equal(0x0003, rng.mask_for_int(3))
96
+ assert_equal(0x0007, rng.mask_for_int(7))
97
+ assert_equal(0x000f, rng.mask_for_int(13))
98
+ end
99
+
100
+ def collect_samples(numSamples = 1e4, &block)
101
+ counts = Hash.new(0)
102
+ numSamples.to_i.times {counts[block.call] += 1}
103
+ counts
104
+ end
105
+
106
+ def test_06_rand_int_limited
107
+ samples = collect_samples {rng.rand_int_limited(0)}
108
+ assert_equal((0..0).to_a, samples.keys.sort)
109
+
110
+ samples = collect_samples {rng.rand_int_limited(1)}
111
+ assert_equal((0..1).to_a, samples.keys.sort)
112
+
113
+ samples = collect_samples {rng.rand_int_limited(10)}
114
+ assert_equal((0..10).to_a, samples.keys.sort)
115
+
116
+ samples = collect_samples {rng.rand_int_limited(30)}
117
+ assert_equal((0..30).to_a, samples.keys.sort)
118
+ end
119
+
120
+ def test_07_rand_num
121
+ samples = collect_samples {rng.rand_num(7, 7)}
122
+ assert_equal((7..7).to_a, samples.keys.sort)
123
+
124
+ samples = collect_samples {rng.rand_num(32, 34)}
125
+ assert_equal((32..34).to_a, samples.keys.sort)
126
+
127
+ samples = collect_samples {rng.rand_num(1, 6)}
128
+ assert_equal((1..6).to_a, samples.keys.sort)
129
+ end
130
+
131
+ def test_08_rand_bytes
132
+ rng = MockRNG.new(0x01020304, 0x050607ff)
133
+ assert_equal(4.chr, rng.rand_bytes(1))
134
+ assert_equal(0xff.chr + 7.chr, rng.rand_bytes(2))
135
+ assert_equal(4.chr + 3.chr + 2.chr, rng.rand_bytes(3))
136
+ assert_equal(0xff.chr + 7.chr + 6.chr + 5.chr, rng.rand_bytes(4))
137
+ assert_equal(4.chr + 3.chr + 2.chr + 1.chr + 0xff.chr, rng.rand_bytes(5))
138
+
139
+ assert_equal(4.chr + 3.chr + 2.chr + 1.chr + 0xff.chr + 7.chr,
140
+ rng.rand_bytes(6))
141
+ assert_equal(4.chr + 3.chr + 2.chr + 1.chr + 0xff.chr + 7.chr + 6.chr,
142
+ rng.rand_bytes(7))
143
+ assert_equal(4.chr + 3.chr + 2.chr + 1.chr +
144
+ 0xff.chr + 7.chr + 6.chr + 5.chr,
145
+ rng.rand_bytes(8))
146
+ assert_equal(4.chr + 3.chr + 2.chr + 1.chr +
147
+ 0xff.chr + 7.chr + 6.chr + 5.chr +
148
+ 4.chr,
149
+ rng.rand_bytes(9))
150
+ end
151
+
152
+ def test_09_add_bits
153
+ assert_equal(0, rng.add_bits(0, 0, 1))
154
+ assert_equal(1, rng.add_bits(0, 1, 1))
155
+ assert_equal(2, rng.add_bits(0, 2, 2))
156
+ assert_equal(3, rng.add_bits(0, 2, 3))
157
+ assert_equal(7, rng.add_bits(1, 2, 3))
158
+ assert_equal(3, rng.add_bits(0, 2, 7))
159
+ assert_equal(10, rng.add_bits(5, 1, 2))
160
+ assert_equal(0xffff, rng.add_bits(1, 15, 0xffff))
161
+ assert_equal(0xfff, rng.add_bits(0, 12, 0xffff))
162
+ assert_equal(-1 + 2**64, rng.add_bits(3, 62, -1 + 2**64))
163
+ end
164
+
165
+ def test_10_rand
166
+ assert_rand(rng)
167
+ end
168
+ end
@@ -0,0 +1,22 @@
1
+ require 'test/unit'
2
+
3
+ require 'random/testing'
4
+ include Random
5
+
6
+ class TestRandomTesting < Test::Unit::TestCase
7
+ def test_01_totally_uniform_should_easily_pass
8
+ assert(Testing.chi_square_test({0 => 5000, 1 => 5000}, 0.1))
9
+ assert(Testing.chi_square_test({0 => 2500, 1 => 2500,
10
+ 2 => 2500, 3 => 2500}, 0.1))
11
+ end
12
+
13
+ def assert_false(v)
14
+ assert(v ? false : true)
15
+ end
16
+
17
+ def test_02_totally_nonuniform_should_fail
18
+ assert_false(Testing.chi_square_test({0 => 0, 1 => 10000}, 0.005))
19
+ assert_false(Testing.chi_square_test({0 => 10, 1 => 10,
20
+ 2 => 9970, 3 => 10}, 0.005))
21
+ end
22
+ end
@@ -0,0 +1,9 @@
1
+ require 'test/unit'
2
+
3
+ require 'random'
4
+
5
+ class TestRNG < Test::Unit::TestCase
6
+ def test_01_MersenneTwister_is_the_default_RNG
7
+ assert_equal(Random::MersenneTwister, Random::RNG)
8
+ end
9
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.11
3
+ specification_version: 1
4
+ name: random
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.2.0
7
+ date: 2006-04-13 00:00:00 +02:00
8
+ summary: Stand-alone random number generator (RNG) class allowing multiple, active RNG's at the same time (which is not possible with Ruby's rand/srand).
9
+ require_paths:
10
+ - lib
11
+ - ext
12
+ - lib
13
+ email: Robert.Feldt@gmail.com
14
+ homepage: http://www.rubyforge.org/projects/random
15
+ rubyforge_project:
16
+ description: A Mersenne-Twister random number generator (RNG) packed up as a class. This allows multiple RNG streams to be active at the same time (which Ruby's normal rand/srand does not allow). The Mersenne-Twister is implemented with fast C code for speed.
17
+ autorequire:
18
+ default_executable:
19
+ bindir: bin
20
+ has_rdoc: false
21
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
22
+ requirements:
23
+ - - ">"
24
+ - !ruby/object:Gem::Version
25
+ version: 0.0.0
26
+ version:
27
+ platform: ruby
28
+ signing_key:
29
+ cert_chain:
30
+ authors:
31
+ - Robert Feldt
32
+ files:
33
+ - README
34
+ - TODO
35
+ - LICENSE
36
+ - VERSION
37
+ - Rakefile
38
+ - ext/random/mersenne_twister_ext.c
39
+ - ext/random/extconf.rb
40
+ - lib/random.rb
41
+ - lib/random/array_random_element.rb
42
+ - lib/random/random_number_generator.rb
43
+ - lib/random/testing.rb
44
+ - lib/math/statistics/chi_square.rb
45
+ - lib/math/statistics/table_chi_square_probabilities.html
46
+ - doc/simple_example.rb
47
+ - test/acceptance/wagner_distribution_1_0
48
+ - test/acceptance/wagner_distribution_1_0/testWagner.out
49
+ - test/acceptance/wagner_distribution_1_0/test_compare_to_wagners_test_output.rb
50
+ - test/performance/test_mersenne_twister.rb
51
+ - test/unit/expected_mersenne_4357.txt
52
+ - test/unit/test_mersenne_twister.rb
53
+ - test/unit/test_random_testing.rb
54
+ - test/unit/test_rng.rb
55
+ - test/unit/test_chi_square.rb
56
+ - test/unit/#mt19937ar.c#
57
+ - test/unit/test_random_number_generator.rb
58
+ test_files: []
59
+
60
+ rdoc_options: []
61
+
62
+ extra_rdoc_files: []
63
+
64
+ executables: []
65
+
66
+ extensions:
67
+ - ext/random/extconf.rb
68
+ requirements: []
69
+
70
+ dependencies: []
71
+