Module:Q-odd-limit intervals: Difference between revisions

gcd no longer needs to be defined here
ArrowHead294 (talk | contribs)
No edit summary
Line 1: Line 1:
bit32 = require ('bit32')
bit32 = require("bit32")
utils = require ('Module:Utils')
utils = require("Module:Utils")


local p = {}
local p = {}
Line 6: Line 6:
local PRIME_LIST = {2, 3, 5, 7, 11, 13, 17, 19, 23}
local PRIME_LIST = {2, 3, 5, 7, 11, 13, 17, 19, 23}


local function is_in (v, t)
local function is_in(v, t)
for i = 1, #t do
for i = 1, #t do
if v == t[i] then
if v == t[i] then
Line 15: Line 15:
end
end


local function table_filter (t, thres)
local function table_filter(t, thres)
for i = 1, #t do
for i = 1, #t do
if t[i] > thres then
if t[i] > thres then
return {unpack (t, 1, i - 1)}
return {unpack(t, 1, i - 1)}
end
end
end
end
Line 24: Line 24:
end
end


local function inner_product (val, monzo)
local function inner_product(val, monzo)
local result = 0
local result = 0
for i = 1, #val do
for i = 1, #val do
result = result + val[i]*monzo[i]
result = result + val[i] * monzo[i]
end
end
return result
return result
end
end


local function monzo2ratio (monzo, subgroup)
local function monzo2ratio(monzo, subgroup)
local num = 1
local num = 1
local den = 1
local den = 1
for i = 1, #subgroup do
for i = 1, #subgroup do
if monzo[i] > 0 then
if monzo[i] > 0 then
num = num*subgroup[i]^monzo[i]
num = num * subgroup[i]^monzo[i]
elseif monzo[i] < 0 then
elseif monzo[i] < 0 then
den = den*subgroup[i]^(-monzo[i])
den = den * subgroup[i]^(-monzo[i])
end
end
end
end
Line 45: Line 45:
end
end


local function ratio2monzo (ratio, subgroup)
local function ratio2monzo(ratio, subgroup)
local monzo = {}
local monzo = {}
for i = 1, #subgroup do
for i = 1, #subgroup do
Line 60: Line 60:
end
end


local function monzo2cent (monzo, subgroup)
local function monzo2cent(monzo, subgroup)
local jip = {}
local jip = {}
for i = 1, #subgroup do
for i = 1, #subgroup do
jip[i] = 1200*utils._log (subgroup[i], 2)
jip[i] = 1200 * utils._log(subgroup[i], 2)
end
end
return inner_product (jip, monzo)
return inner_product(jip, monzo)
end
end


local function ratio_8ve_reduction (ratio)
local function ratio_8ve_reduction(ratio)
local oct = math.floor (utils._log (ratio.num/ratio.den, 2))
local oct = math.floor(utils._log(ratio.num / ratio.den, 2))
if oct > 0 then
if oct > 0 then
ratio.den = ratio.den * 2^oct
ratio.den = ratio.den * 2^oct
Line 78: Line 78:
end
end


local function odd_limit_monzo_list_gen (limit)
local function odd_limit_monzo_list_gen(limit)
local monzo_list = {}
local monzo_list = {}
local subgroup = table_filter (PRIME_LIST, limit)
local subgroup = table_filter(PRIME_LIST, limit)
for num = 1, limit, 2 do
for num = 1, limit, 2 do
for den = 1, num, 2 do
for den = 1, num, 2 do
if utils._gcd (num, den) == 1 then
if utils._gcd(num, den) == 1 then
ratio = ratio_8ve_reduction ({num = num, den = den})
ratio = ratio_8ve_reduction({num = num, den = den})
table.insert (monzo_list, ratio2monzo (ratio, subgroup))
table.insert(monzo_list, ratio2monzo(ratio, subgroup))
end
end
end
end
Line 92: Line 92:
end
end


local function find_error (val, subgroup, monzo_list)
local function find_error(val, subgroup, monzo_list)
local step_size = 1200/val[1]
local step_size = 1200/val[1]
local true_size
local true_size
Line 98: Line 98:
local error_list = {}
local error_list = {}
for i = 1, #monzo_list do
for i = 1, #monzo_list do
ratio = monzo2ratio (monzo_list[i], subgroup)
ratio = monzo2ratio(monzo_list[i], subgroup)
comp = {2*ratio.den, ratio.num}
comp = {2 * ratio.den, ratio.num}
true_size = monzo2cent (monzo_list[i], subgroup)
true_size = monzo2cent(monzo_list[i], subgroup)
approx_size = step_size*inner_product (val, monzo_list[i])
approx_size = step_size * inner_product(val, monzo_list[i])
error_abs = math.abs (approx_size - true_size)
error_abs = math.abs(approx_size - true_size)
error_rel = 100*error_abs/step_size
error_rel = 100 * error_abs / step_size
error_list[i] =  
error_list[i] =  
{
{
Line 112: Line 112:
}
}
end
end
table.sort (error_list, function (a, b) return a.error_abs < b.error_abs end)
table.sort(error_list, function(a, b) return a.error_abs < b.error_abs end)
return error_list
return error_list
end
end


local function approx (steps, subgroup, monzo_list, t_title)
local function approx(steps, subgroup, monzo_list, t_title)
local t_body = {}
local t_body = {}
local val = {}
local val = {}
for i = 1, #subgroup do
for i = 1, #subgroup do
val[i] = utils._round_dec (steps*utils._log (subgroup[i], 2))
val[i] = utils._round_dec(steps*utils._log(subgroup[i], 2))
end
end
error_list = find_error (val, subgroup, monzo_list)
error_list = find_error(val, subgroup, monzo_list)
for i = 1, #error_list do
for i = 1, #error_list do
ratiocomp = string.format ("%d/%d, %d/%d", error_list[i].ratio.num, error_list[i].ratio.den, 2*error_list[i].ratio.den, error_list[i].ratio.num)
ratiocomp = string.format("%d/%d, %d/%d", error_list[i].ratio.num, error_list[i].ratio.den, 2 * error_list[i].ratio.den, error_list[i].ratio.num)
error_abs = string.format ("%.3f", error_list[i].error_abs)
error_abs = string.format("%.3f", error_list[i].error_abs)
error_rel = string.format ("%.1f", error_list[i].error_rel)
error_rel = string.format("%.1f", error_list[i].error_rel)
if bit32.band (error_list[i].ratio.den, error_list[i].ratio.den - 1) == 0 and is_in (error_list[i].ratio.num, subgroup) then -- check power of 2 for den and prime for num
if bit32.band(error_list[i].ratio.den, error_list[i].ratio.den - 1) == 0 and is_in(error_list[i].ratio.num, subgroup) then -- check power of 2 for den and prime for num
ratiocomp = "'''" .. ratiocomp .. "'''"
ratiocomp = "'''" .. ratiocomp .. "'''"
error_abs = "'''" .. error_abs .. "'''"
error_abs = "'''" .. error_abs .. "'''"
error_rel = "'''" .. error_rel .. "'''"
error_rel = "'''" .. error_rel .. "'''"
end if error_list[i].error_rel > 50 then
end if error_list[i].error_rel > 50 then
ratiocomp = "''" .. ratiocomp .. "''"
ratiocomp = "''<span style=\"background-color: #aaaaaa;\">" .. ratiocomp .. "<\/span>''"
error_abs = "''" .. error_abs .. "''"
error_abs = "''<span style=\"background-color: #aaaaaa;\">" .. error_abs .. "<\/span>''"
error_rel = "''" .. error_rel .. "''"
error_rel = "''<span style=\"background-color: #aaaaaa;\">" .. error_rel .. "<\/span>''"
end
end
t_body[i] = string.format ("|-\n| %s\n| %s\n| %s", ratiocomp, error_abs, error_rel)
t_body[i] = string.format("|-\n| %s\n| %s\n| %s", ratiocomp, error_abs, error_rel)
end
end


return "{| class=\"wikitable center-all mw-collapsible mw-collapsed\"\n" ..
return "{| class=\"wikitable center-all mw-collapsible mw-collapsed\"\n" ..
"|+style=white-space:nowrap| " .. t_title .. "\n" ..
"|+ style=\"white-space: nowrap;\" | " .. t_title .. "\n" ..
"|-\n" ..
"|-\n" ..
"! Interval, complement\n" ..
"! Interval, complement\n" ..
"! Error (abs, [[Cent|¢]])\n" ..
"! Error (abs, [[Cent|¢]])\n" ..
"! Error (rel, [[Relative cent|%]])\n" ..
"! Error (rel, [[Relative cent|%]])\n" ..
table.concat (t_body, "\n") ..
table.concat(t_body, "\n") ..
"\n|}"
"\n|}"
end
end
Line 153: Line 153:
-- end
-- end


function p.odd_limit (frame)
function p.odd_limit(frame)
local steps = tonumber (frame.args['steps'])
local steps = tonumber(frame.args["steps"])
local limit = math.max (tonumber (frame.args['limit']), 2)
local limit = math.max(tonumber (frame.args["limit"]), 2)
-- local prec = tonumber (frame.args['prec']) or prec_by_equal (steps)
-- local prec = tonumber (frame.args['prec']) or prec_by_equal (steps)
local title = frame.args['title']
local title = frame.args["title"]
if title == nil or #title == 0 then
if title == nil or #title == 0 then
title = string.format ("%d-odd-limit intervals by patent val mapping", limit)
title = string.format("%d-odd-limit intervals by patent val mapping", limit)
end
end
local subgroup = table_filter (PRIME_LIST, limit)
local subgroup = table_filter(PRIME_LIST, limit)
local monzo_list = odd_limit_monzo_list_gen (limit)
local monzo_list = odd_limit_monzo_list_gen(limit)


return approx (steps, subgroup, monzo_list, title)
return approx(steps, subgroup, monzo_list, title)
end
end


return p;
return p;