The file is part of the BURN project (learing multi-objective rules).
Because learning is not the filling a pail, but the lighting of a fire.
Burn=require "burn"local lib= {
E = 2.7182818285,
PI = 3.1415926536,
abs = math.abs,
int = math.floor,
printf = function(s, ...) return io.write(s:format(...)) end,
sprintf= function(s, ...) return s:format(...) end,
match = function(s,p) return string.match(s,p) ~= nil end}Returns m rounded to the nearest n. E.g.
round(32.7812, 0.1) returns 32.8.
function lib.round(exact, quantum)
local quant,frac = math.modf(exact/quantum)
return quantum * (quant + (frac > 0.5 and 1 or 0))
endReturn true are m and n are within e% of each other
(default value for e = 1).
function lib.close(m,n,e)
e = e and e or 1
return lib.abs(m-n)/n <= e/100
endfunction lib.max(a,b) return a > b and a or b endfunction lib.min(a,b) return a < b and a or b enddo
local seed0 = 10013
local seed = seed0
local modulus = 2147483647
local multipler = 16807
function lib.rseed(n) seed = n or seed0 end
function lib.rand() -- park miller
seed = (multipler * seed) % modulus
return seed / modulus end
endReturn a y value for x by interpolating across the points in xs,ys.
E.g.
interpolate(3,{1,2,4},{10,20,40}) returns 30,
This function assumes that y changes linearly between the
points records in xs,ys. Also, anything less or more than
the first and last values in xs are capped to the ys[1] or ys[#ys]
values, respectively.
function lib.interpolate(x,xs,ys, x1,y1)
local x0, y0 = xs[1], ys[1]
if x <= x0 then return y0 end
if x > xs[ #xs ] then return ys[ #ys ] end
for i = 1, #xs do
x1,y1 = xs[i],ys[i]
if x0 <= x and x < x1 then break end
x0, y0 = x1, y1 end
return y0 + (x - x0)/(x1 - x0) * (y1 - y0)
endfunction lib.weibull(x,l,k)
return x < 0 and 0 or k/l*(x/l)^(k-1)*E^(-1*(x/l)^k)
endfunction lib.weibullCdf(x,l,k)
return x < 0 and 0 or 1 - E^(-(x/l)^k)
endfunction lib.normal(x, mu, sigma)
return E^(-.5 * (x-mu)*(x-mu)/(sigma*sigma)) /
math.sqrt(2.0*math.pi*sigma*sigma)
endfunction lib.normCdf(x, mu, sigma)
return 0.5 * (1.0 + E^((x-mu)/math.sqrt(2*sigma*sigma)))
endfunction lib.ordered(t)
local i,tmp = 0,{}
for key,_ in pairs(t) do tmp[#tmp+1] = key end
table.sort(tmp)
return function ()
if i < #tmp then
i=i+1; return tmp[i], t[tmp[i]] end end
end
function lib.eras(src,era)
local era = era or 32
local e,tmp,out,one = 0,{},{},src()
return function()
while one do
tmp[ #tmp+1 ] = one
one = src()
if #tmp >= era then
out = lib.shuffle(lib.copy(tmp))
tmp,e = {},e+1
return out,e end
end
if #tmp > 0 then
out = lib.shuffle(lib.copy(tmp))
tmp,e = {},e+1
return out,e end end
endfunction lib.sorted(t, f)
f = f or function (x,y) return x<y end
table.sort(t,f)
return t
endfunction lib.member(x,t)
for _,y in pairs(t) do if x==y then return true end end
return false
endfunction lib.slice(t, i,j)
local out={}
for k=i,j do out[#out+1] = t[k] end
return out
endfunction lib.push(x,t)
t[ #t+1 ] = x; return x
endfunction lib.join(t, sep)
local u ={}
for i,x in pairs(t) do u[i] = tostring(x) end
return table.concat(u, sep or ", ")
endfunction lib.any(t)
local pos = math.floor(0.5 + lib.rand() * #t)
return t[ lib.min(#t,lib.max(1,pos)) ]
endfunction lib.anys(t,n)
t = lib.shuffle(t)
a,b = {},{}
for i=1,n do a[#a+1] = t[i] end
for i=n+1,#t do b[#b+1] = t[i] end
return a,b
endfunction lib.merge(t1,t2)
for _,x in pairs(t2) do t1[#t1+1] = x end
return t1
endfunction lib.shuffle( t )
for i= 1,#t do
local j = i + math.floor((#t - i) * lib.rand() + 0.5)
t[i],t[j] = t[j], t[i] end
return t
endfunction lib.shallowCopy(t)
return lib.collect(t,lib.same)
endfunction lib.copy(t) --recursive
return type(t) ~= 'table' and t or lib.collect(t,lib.copy)
endReading from updates (or, if missing, arg),
ignoring any flags listed in ignore, update settings
with command-line settings such as -k a=1 b=2
(which sets k to true and a,b to 1,2).
function lib.args(settings,ignore, updates)
updates = updates or arg
ignore = ignore or {}
local i = 1
while updates[i] ~= nil do
local flag = updates[i]
local b4 = #flag
flag = flag:gsub("^[-]+","")
if not lib.member(flag,ignore) then
if settings[flag] == nil then
error("unknown flag '" .. flag .. "'")
else
if b4 - #flag == 2 then settings[flag] = true
elseif b4 - #flag == 1 then
local a1 = updates[i+1]
local a2 = tonumber(a1)
settings[flag] = a2 or a1
i = i + 1 end end end
i = i + 1 end
return settings
endfunction lib.say(x) io.write(tostring(x)); io.flush() endfunction lib.scan(s) return tonumber(s) or s endfunction lib.rep(s, n) return n > 0 and s .. lib.rep(s, n-1) or "" endReturn a table of cells generated by spliting s on sep.
function lib.split(s, sep)
local t, sep = {}, sep or ","
local notsep = "([^" ..sep.. "]+)"
for y in string.gmatch(s, notsep) do t[#t+1] = y end
return t
endExtract substrings. Allow Python style negative indexes
function lib.sub(s,lo,hi)
if lo and lo < 0 then
return lib.sub(s, string.len(s) + lo +1)
else
return string.sub(s,lo and lo or 1,hi) end
endPrint anything, including nested things
If you want the string, without printing it,
use ooo(x).
function lib.oo(data) print(lib.ooo(data)) end
function lib.ooo(data)
local seen={}
local function go(x, str,sep)
if type(x) ~= "table" then return tostring(x) end
if seen[x] then return "..." end
seen[x] = true
for k,v in lib.ordered(x) do
str = str .. sep .. k .. ": " .. go(v, "{","")
sep = ", " end
return str .. '}'
end
return go(data,"{","")
endPretty print the list of lists in t.
If numfmt suppied, use it to format numbers.
If noline then suppress the underlines beneath row1.
function lib.cols(t, numfmt, noline)
local w={}
for i,_ in pairs(t[1]) do w[i] = 0 end
for i,line in pairs(t) do
for j,cell in pairs(line) do
if type(cell)=="number" and numfmt then
cell = lib.sprintf(numfmt, cell)
t[i][j] = cell end
w[j] = lib.max( w[j], #tostring(cell) ) end end
for n,line in pairs(t) do
local txt,sep="",""
for j,cell in pairs(line) do
local fmt = "%" .. (w[j]+1) .. "s"
txt = txt .. sep .. lib.sprintf(fmt, cell)
sep = ","
end
print(txt)
if (n==1 and not noline) then
local sep="#"
for _,w1 in pairs(w) do
io.write(sep .. string.rep("-",w1) )
sep=", " end
print("") end end
endfunction lib.same(x) return x endfunction lib.map(t,f)
if t then for i,v in pairs(t) do f(v) end end
endfunction lib.map2(t,i,f)
if t then for _,v in pairs(t) do f(i,v) end end
return i
endfunction lib.collect(t,f)
local out={}
if t then for i,v in pairs(t) do out[i] = f(v) end end
return out
endfunction lib.select(t,f)
local out={}
if t then for i,v in pairs(t) do
if f(v) then out[#out + 1]=v end end end
return out
endReject all results that do not satisfy f(v) for each item v in t.
function lib.reject(t,f)
return lib.select(t, function(v) return not f(v) end)
endfunction lib.when(f, r)
r= r or 1
local t1=os.clock()
for _=1,r do f() end
return (os.clock() - t1)/ r
endreturn lib