Difference between revisions of "Module:Pyrandom"
Jump to navigation
Jump to search
(One intermediate revision by the same user not shown) | |||
Line 62: | Line 62: | ||
end | end | ||
− | return start + self:_randbelow(stop) | + | return start + self:_randbelow(stop - start) |
end | end | ||
function instance:choice(array) | function instance:choice(array) | ||
− | local r = self:_randbelow(#array | + | local r = self:_randbelow(#array) |
return array[r + 1] | return array[r + 1] | ||
end | end |
Latest revision as of 15:31, 11 June 2021
Documentation for this module may be created at Module:Pyrandom/doc
local bit32 = require "bit32"
local mt = require "Module:Mt19937ar"
function bit_length(n)
local l = 0
while n > 0 do
l = l + 1
n = bit32.rshift(n, 1)
end
return l
end
local pyrandom = {}
function pyrandom.new(str)
local instance = {}
function instance:seed(str)
local seed = ""
for i = 1, #str do
seed = seed .. string.format('%02x', string.byte(str, i))
end
seed = seed .. mw.hash.hashValue("sha512", str)
seed = string.rep('0', (8 - (#seed % 8)) % 8) .. seed
seed_array = {}
for i = #seed, 1, -8 do
table.insert(seed_array, tonumber(string.sub(seed, i-7, i), 16))
end
local mt = mt.new()
mt:init_by_array(seed_array)
return mt
end
local rand = instance:seed(str)
function instance:random()
return rand:genrand_res53()
end
function instance:getrandbits(k)
if k == 0 then
return 0
end
return bit32.rshift(rand:genrand_int32(), (32 - k))
end
function instance:_randbelow(n)
if n == 0 then
return 0
end
local k = bit_length(n)
local r = self:getrandbits(k)
while r >= n do
r = self:getrandbits(k)
end
return r
end
function instance:randrange(start, stop)
if (stop == nil) then
return self:_randbelow(start)
end
return start + self:_randbelow(stop - start)
end
function instance:choice(array)
local r = self:_randbelow(#array)
return array[r + 1]
end
local gauss_next = nil
function instance:gauss(mu, sigma)
local z = gauss_next
gauss_next = nil
if z == nil then
local x2pi = self:random() * math.pi * 2
local g2rad = math.sqrt(-2.0 * math.log(1.0 - self:random()))
z = math.cos(x2pi) * g2rad
gauss_next = math.sin(x2pi) * g2rad
end
return mu + z * sigma
end
return instance
end
return pyrandom