Random number generators in Ruby - linear congruential, additive congruential, chi-square test built into the generator code.
See also : RandomNormalDistribution
class GRnd # abstract randomizer class
def initialize(seed)
@seed = seed
end
attr_reader :seed
def rand
return nil
end
def chisquare(n, r)
f = []
f.fill(0, 0..r)
1.upto(n) do |i|
t = rand_n_m(0, r)
f[t] += 1
end
t = 0; 0.upto(r-1) {|i| t += f[i] * f[i] }
return (r * t / n) - n
end
def reset
end
end
class LCRnd < GRnd # linear congruential method
def initialize(seed, b = 31415821, m = 100000000)
super(seed)
@b, @m = b, m
@prev = seed
end
attr_reader :b, :m
def rand_n_m(n, m) # return an integer from [n,m]
n,m = m,n if n > m
return (rand01 * (m - n) + n).floor
end
def rand01 # return a float from [0,1)
return rand.to_f / @m
end
def rand # return an integer from [0,m-1]
@prev = (@prev * @b + 1) % @m
end
def reset
@prev = @seed
end
end
class ACRnd < LCRnd # additive congruential method
def initialize(seed, sz = 55, b = 31415821, m = 100000000)
super(seed, b, m)
lrc = LCRnd.new(seed,b,m)
@sz = sz
@a = []
0.upto(sz - 1) {|i| @a[i] = lrc.rand()}
@j = sz - 1
@n1 = (@j + 1) / 2
@n2 = @j - 1
end
attr_reader :sz
def rand
@j = (@j + 1) % sz
@a[@j] = (@a[(@j + @n1) % sz] + @a[(@j + @n2) % sz]) % m
end
end
if __FILE__ == $0
puts "--------- Results of linear congruential method"
r = LCRnd.new(511)
puts "---- rand ----"
delim="";100.times {print "#{delim}#{r.rand}"; delim=","}
puts "\n---- rand01 ----"
delim="";100.times {print "#{delim}#{r.rand01}"; delim=","}
puts "\n---- rand_n_m"
delim="";100.times {print "#{delim}#{r.rand_n_m(1, 100)}"; delim=","}
puts "\n chisquare = #{r.chisquare(1000,100)}"
puts "--------- Results of additive congruential method"
r = ACRnd.new(511)
puts "---- rand ----"
delim="";100.times {print "#{delim}#{r.rand}"; delim=","}
puts "\n---- rand01 ----"
delim="";100.times {print "#{delim}#{r.rand01}"; delim=","}
puts "\n---- rand_n_m"
delim="";100.times {print "#{delim}#{r.rand_n_m(1, 100)}"; delim=","}
puts "\n chisquare = #{r.chisquare(1000,100)}"
end
-- DaleBrayden - 07 Sep 2002