Module:Uniform map: Difference between revisions
m Replace JIP with just_tuning_map |
merge changes from dev |
||
| Line 1: | Line 1: | ||
local getArgs = require( | local getArgs = require("Module:Arguments").getArgs | ||
local | local utils = require("Module:Utils") | ||
local p = {} | local p = {} | ||
-- stylua: ignore | |||
p.lower = { | local warts = { | ||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', | |||
'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', | |||
's', 't', 'u', 'v', 'w', 'x', 'y', 'z' | |||
} | |||
function p.new() | |||
local m = {} | |||
m.map = {} -- The prime map | |||
m.lower = {} -- List of smallest sizes that match a map for each prime | |||
m.upper = {} -- List of largest sizes that match a map for each prime | |||
m.pbi = 0 -- Index of the prime that defines the boundary | |||
return m | |||
end | |||
-- Find the minimum size that corresponds to a given map | -- Find the minimum size that corresponds to a given map | ||
function p. | function p.lower_bound(m) | ||
local lowermax | local lowermax | ||
for i=1, #map do | for i = 1, #m.map do | ||
m.lower[i] = (m.map[i] - 0.5) / utils.log2(utils.primes[i]) | |||
lowermax = math.max(unpack( | lowermax = math.max(unpack(m.lower)) | ||
end | end | ||
return math.max(0, lowermax) | return math.max(0, lowermax) | ||
| Line 19: | Line 30: | ||
-- Find the maximum size that corresponds to a given map | -- Find the maximum size that corresponds to a given map | ||
function p. | function p.upper_bound(m) | ||
local uppermin | local uppermin | ||
for i=1, #map do | for i = 1, #m.map do | ||
m.upper[i] = (m.map[i] + 1 / 2) / utils.log2(utils.primes[i]) | |||
uppermin = math.min(unpack( | uppermin = math.min(unpack(m.upper)) | ||
pbi = | m.pbi = utils.index_of(m.upper, uppermin) | ||
end | end | ||
return math.max(0, uppermin) | return math.max(0, uppermin) | ||
| Line 31: | Line 42: | ||
-- Find the p-limit just tuning map corresponding to a given size | -- Find the p-limit just tuning map corresponding to a given size | ||
function p.just_tuning_map(size, prime) | function p.just_tuning_map(size, prime) | ||
local | prime = tonumber(prime) | ||
for i=1, | local p_index = utils.index_of(utils.primes, prime) | ||
assert(p_index ~= nil, "index of prime " .. prime .. " not found") | |||
local just_tuning_map = {} | |||
for i = 1, utils.index_of(utils.primes, prime) do | |||
just_tuning_map[i] = size * utils.log2(utils.primes[i]) | |||
end | end | ||
return | return just_tuning_map | ||
end | end | ||
-- Find the p-limit simple map corresponding to a given size | -- Find the p-limit simple map corresponding to a given size | ||
function p.simple_map(size, prime) | function p.simple_map(size, prime) | ||
prime = tonumber(prime) | |||
local p_index = utils.index_of(utils.primes, prime) | |||
assert(p_index ~= nil, "index of prime " .. prime .. " not found") | |||
local simple_map = {} | |||
for i = 1, p_index do | |||
simple_map[i] = math.floor(0.5 + size * utils.log2(utils.primes[i])) | |||
end | end | ||
return | return simple_map | ||
end | end | ||
| Line 50: | Line 67: | ||
function p.wart(map) | function p.wart(map) | ||
local edo = map[1] | local edo = map[1] | ||
local simple_map_edo = p.simple_map(edo, | local simple_map_edo = p.simple_map(edo, utils.primes[#map]) | ||
local just_tuning_map_edo = p.just_tuning_map(edo, | local just_tuning_map_edo = p.just_tuning_map(edo, utils.primes[#map]) | ||
local wart_notation = edo | local wart_notation = edo | ||
for i=2, #map do | for i = 2, #map do | ||
-- direction is 1 if current harmonic mapped flatter than just, otherwise 0 | -- direction is 1 if current harmonic mapped flatter than just, otherwise 0 | ||
local direction = math.ceil(just_tuning_map_edo[i]-simple_map_edo[i]) | local direction = math.ceil(just_tuning_map_edo[i] - simple_map_edo[i]) | ||
local difference = map[i]-simple_map_edo[i] | local difference = map[i] - simple_map_edo[i] | ||
if difference ~= 0 then | if difference ~= 0 then | ||
number_warts = (2*math.abs(difference)+( | local number_warts = (2 * math.abs(difference) + (utils.signum((-1) ^ direction * difference) - 1) / 2) | ||
for | for _ = 1, number_warts do | ||
wart_notation = wart_notation .. warts[i] | wart_notation = wart_notation .. warts[i] | ||
end | end | ||
end | end | ||
end | end | ||
return wart_notation | |||
end | end | ||
-- Generate table of p-limit uniform maps between min and max, for use with print_table | -- Generate table of p-limit uniform maps between min and max, for use with print_table | ||
-- Could potentially be used standalone for raw data with headers | |||
function p.make_table(prime, min, max) | function p.make_table(prime, min, max) | ||
local maptable = {} -- Table of uniform maps with boundaries and wart notation | |||
local maptable = {} | local map_table = p.new() | ||
map_table.map = p.simple_map(min, prime) -- Set p-limit map for minimum size | |||
local lb = p.lower_bound(map_table) -- Minimum size for the current map | |||
local ub = p.upper_bound(map_table) -- Maximum size for the current map | |||
local row = { "Min. size", "Max. size", "[[Wart notation]]" } | |||
for i = 1, #map_table.map do | |||
table.insert(row, utils.primes[i]) | |||
local lb = p. | |||
local ub = p. | |||
local row = { | |||
for i=1, #map do | |||
table.insert(row, | |||
end | end | ||
table.insert(maptable, row) | table.insert(maptable, row) | ||
while lb < max do | while lb < max do | ||
row = {string.format("%.4f", lb), string.format("%.4f", ub), p.wart(map)} | row = { string.format("%.4f", lb), string.format("%.4f", ub), p.wart(map_table.map) } | ||
for j=1, #map do | for j = 1, #map_table.map do | ||
table.insert(row, map[j]) | table.insert(row, map_table.map[j]) | ||
end | end | ||
table.insert(maptable, row) | table.insert(maptable, row) | ||
map[pbi] = map[pbi] + 1 | map_table.map[map_table.pbi] = map_table.map[map_table.pbi] + 1 | ||
lb = p. | lb = p.lower_bound(map_table) | ||
ub = p. | ub = p.upper_bound(map_table) | ||
end | end | ||
return maptable | return maptable | ||
| Line 105: | Line 116: | ||
local min = args[2] | local min = args[2] | ||
local max = args[3] | local max = args[3] | ||
if | if utils.index_of(utils.primes, utils.eval_num_arg(prime, 5)) == nil then | ||
prime = 5 | prime = 5 -- Default to 5-limit | ||
end | end | ||
luatable = p.make_table(prime, | local luatable = p.make_table(prime, utils.eval_num_arg(min, 11.5), utils.eval_num_arg(max, 12.5)) | ||
wikitable = string.format('{| class="wikitable"\n|+ %d-limit [[uniform map]]s between %g and %g', prime, min, max) | local wikitable = | ||
for i=1, 3 do | string.format('{| class="wikitable"\n|+ %d-limit [[uniform map]]s between %g and %g', prime, min, max) | ||
wikitable = wikitable .. | for i = 1, 3 do | ||
wikitable = wikitable .. "\n! " .. luatable[1][i] | |||
end | end | ||
wikitable = wikitable .. | wikitable = wikitable .. "\n! Map" | ||
for i=2, #luatable do | for i = 2, #luatable do | ||
wikitable = wikitable .. | wikitable = wikitable .. "\n|-" | ||
for j=1, 3 do | for j = 1, 3 do | ||
wikitable = wikitable .. | wikitable = wikitable .. "\n| " .. luatable[i][j] | ||
end | end | ||
local wikimap = | local wikimap = "" | ||
for j=4, #luatable[i] do | for j = 4, #luatable[i] do | ||
wikimap = wikimap .. | wikimap = wikimap .. " " .. luatable[i][j] | ||
end | end | ||
wikitable = wikitable .. | wikitable = wikitable .. "\n| " .. frame:expandTemplate({ title = "map", args = { wikimap } }) | ||
end | end | ||
wikitable = wikitable .. | wikitable = wikitable .. "\n|}" | ||
return wikitable | |||
end | end | ||
return p | return p | ||