Module:Uniform map: Difference between revisions

From Xenharmonic Wiki
Jump to navigation Jump to search
m Replace JIP with just_tuning_map
Sintel (talk | contribs)
merge changes from dev
Line 1: Line 1:
local getArgs = require('Module:Arguments').getArgs
local getArgs = require("Module:Arguments").getArgs
local u = require('Module:Utils')
local utils = require("Module:Utils")
local p = {}
local p = {}


p.primes = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97}
-- stylua: ignore
p.lower = {0, 0 ,0} -- List of smallest sizes that match a map for each prime
local warts = {
p.upper = {0, 0, 0} -- List of largest sizes that match a map for each prime
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
p.pbi = 0           -- Index of the prime that defines the boundary
    '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.lowerbound(map)
function p.lower_bound(m)
local lowermax
local lowermax
for i=1, #map do
for i = 1, #m.map do
p.lower[i] = (map[i]-1/2)/u._log(p.primes[i])
m.lower[i] = (m.map[i] - 0.5) / utils.log2(utils.primes[i])
lowermax = math.max(unpack(p.lower))
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.upperbound(map)
function p.upper_bound(m)
local uppermin
local uppermin
for i=1, #map do
for i = 1, #m.map do
p.upper[i] = (map[i]+1/2)/u._log(p.primes[i])
m.upper[i] = (m.map[i] + 1 / 2) / utils.log2(utils.primes[i])
uppermin = math.min(unpack(p.upper))
uppermin = math.min(unpack(m.upper))
pbi = u.index_of(p.upper, uppermin)
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 just_tuning_map_table = {}
prime = tonumber(prime)
for i=1, u.index_of(p.primes, prime) do
local p_index = utils.index_of(utils.primes, prime)
just_tuning_map_table[i] = size*u._log(p.primes[i])
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 just_tuning_map_table
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)
local simple_map_table = {}
prime = tonumber(prime)
for i=1, u.index_of(p.primes, prime) do
local p_index = utils.index_of(utils.primes, prime)
simple_map_table[i] = u._round_dec(size*u._log(p.primes[i]))
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 simple_map_table
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, p.primes[#map])
local simple_map_edo = p.simple_map(edo, utils.primes[#map])
local just_tuning_map_edo = p.just_tuning_map(edo, p.primes[#map])
local just_tuning_map_edo = p.just_tuning_map(edo, utils.primes[#map])
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'}
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)+(u.signum((-1)^direction*difference)-1)/2)
local number_warts = (2 * math.abs(difference) + (utils.signum((-1) ^ direction * difference) - 1) / 2)
for j=1,number_warts do
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
return wart_notation
end
end


-- Generate table of p-limit uniform maps between min and max, for use with print_table (but could potentially be used standalone for raw data with headers)
-- 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 map = {}
local maptable = {} -- Table of uniform maps with boundaries and wart notation
local maptable = {}                     -- Table of uniform maps with boundaries and wart notation
local map_table = p.new()
prime = u.eval_num_arg(prime, 5)
map_table.map = p.simple_map(min, prime) -- Set p-limit map for minimum size
for i=1, u.index_of(p.primes, prime) do
local lb = p.lower_bound(map_table) -- Minimum size for the current map
map[i] = 0                          -- Reset to p-limit null map
local ub = p.upper_bound(map_table) -- Maximum size for the current map
p.lower[i] = 0
local row = { "Min. size", "Max. size", "[[Wart notation]]" }
p.upper[i] = 0
for i = 1, #map_table.map do
end
table.insert(row, utils.primes[i])
map = p.simple_map(min, prime)         -- Set p-limit map for minimum size
local lb = p.lowerbound(map) -- Minimum size for the current map
local ub = p.upperbound(map) -- Maximum size for the current map
local row = {'Min. size', 'Max. size', '[[Wart notation]]'}
for i=1, #map do
table.insert(row, p.primes[i])
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.lowerbound(map)
lb = p.lower_bound(map_table)
ub = p.upperbound(map)
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 u.index_of(p.primes, u.eval_num_arg(prime, 5)) == nil then
if utils.index_of(utils.primes, utils.eval_num_arg(prime, 5)) == nil then
prime = 5                         -- Default to 5-limit
prime = 5 -- Default to 5-limit
end
end
luatable = p.make_table(prime, u.eval_num_arg(min, 11.5), u.eval_num_arg(max, 12.5))
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 .. '\n! ' .. luatable[1][i]
for i = 1, 3 do
wikitable = wikitable .. "\n! " .. luatable[1][i]
end
end
wikitable = wikitable .. '\n! Map'
wikitable = wikitable .. "\n! Map"
for i=2, #luatable do
for i = 2, #luatable do
wikitable = wikitable .. '\n|-'
wikitable = wikitable .. "\n|-"
for j=1, 3 do
for j = 1, 3 do
wikitable = wikitable .. '\n| ' .. luatable[i][j]
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 .. ' ' .. luatable[i][j]
wikimap = wikimap .. " " .. luatable[i][j]
end
end
wikitable = wikitable .. '\n| ' .. frame:expandTemplate{title = 'map', args = {wikimap}}
wikitable = wikitable .. "\n| " .. frame:expandTemplate({ title = "map", args = { wikimap } })
end
end
wikitable = wikitable .. '\n|}'
wikitable = wikitable .. "\n|}"
    return wikitable
return wikitable
end
end


return p
return p

Revision as of 20:16, 1 April 2024

Module documentation[view] [edit] [history] [purge]
This module should not be invoked directly; use its corresponding template instead: Template:Uniform map.

This module is called by Template:Uniform map to produce a table of p-limit uniform maps between two size boundaries.

Introspection summary for Module:Uniform map 
Functions provided (8)
Line Function Params
12 new none
22 lower_bound (m)
32 upper_bound (m)
43 just_tuning_map (size, prime)
55 simple_map (size, prime)
67 wart (map)
88 make_table (prime, min, max)
113 print_table (invokable) (frame)
Lua modules required (2)
Variable Module Functions used
getArgs Module:Arguments getArgs
utils Module:Utils log2
index_of
signum
eval_num_arg

No function descriptions were provided. The Lua code may have further information.


local getArgs = require("Module:Arguments").getArgs
local utils = require("Module:Utils")
local p = {}

-- stylua: ignore
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
function p.lower_bound(m)
	local lowermax
	for i = 1, #m.map do
		m.lower[i] = (m.map[i] - 0.5) / utils.log2(utils.primes[i])
		lowermax = math.max(unpack(m.lower))
	end
	return math.max(0, lowermax)
end

-- Find the maximum size that corresponds to a given map
function p.upper_bound(m)
	local uppermin
	for i = 1, #m.map do
		m.upper[i] = (m.map[i] + 1 / 2) / utils.log2(utils.primes[i])
		uppermin = math.min(unpack(m.upper))
		m.pbi = utils.index_of(m.upper, uppermin)
	end
	return math.max(0, uppermin)
end

-- Find the p-limit just tuning map corresponding to a given size
function p.just_tuning_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 just_tuning_map = {}
	for i = 1, utils.index_of(utils.primes, prime) do
		just_tuning_map[i] = size * utils.log2(utils.primes[i])
	end
	return just_tuning_map
end

-- Find the p-limit simple map corresponding to a given size
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
	return simple_map
end

-- Find the wart notation corresponding to a given map
function p.wart(map)
	local edo = map[1]
	local simple_map_edo = p.simple_map(edo, utils.primes[#map])
	local just_tuning_map_edo = p.just_tuning_map(edo, utils.primes[#map])
	local wart_notation = edo
	for i = 2, #map do
		-- 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 difference = map[i] - simple_map_edo[i]
		if difference ~= 0 then
			local number_warts = (2 * math.abs(difference) + (utils.signum((-1) ^ direction * difference) - 1) / 2)
			for _ = 1, number_warts do
				wart_notation = wart_notation .. warts[i]
			end
		end
	end
	return wart_notation
end

-- 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)
	local maptable = {} -- Table of uniform maps with boundaries and wart notation
	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])
	end
	table.insert(maptable, row)
	while lb < max do
		row = { string.format("%.4f", lb), string.format("%.4f", ub), p.wart(map_table.map) }
		for j = 1, #map_table.map do
			table.insert(row, map_table.map[j])
		end
		table.insert(maptable, row)
		map_table.map[map_table.pbi] = map_table.map[map_table.pbi] + 1
		lb = p.lower_bound(map_table)
		ub = p.upper_bound(map_table)
	end
	return maptable
end

-- Print wiki-formatted table (string) of p-limit uniform maps between min and max
function p.print_table(frame)
	local args = getArgs(frame)
	local prime = args[1]
	local min = args[2]
	local max = args[3]
	if utils.index_of(utils.primes, utils.eval_num_arg(prime, 5)) == nil then
		prime = 5 -- Default to 5-limit
	end
	local luatable = p.make_table(prime, utils.eval_num_arg(min, 11.5), utils.eval_num_arg(max, 12.5))
	local wikitable =
		string.format('{| class="wikitable"\n|+ %d-limit [[uniform map]]s between %g and %g', prime, min, max)
	for i = 1, 3 do
		wikitable = wikitable .. "\n! " .. luatable[1][i]
	end
	wikitable = wikitable .. "\n! Map"
	for i = 2, #luatable do
		wikitable = wikitable .. "\n|-"
		for j = 1, 3 do
			wikitable = wikitable .. "\n| " .. luatable[i][j]
		end
		local wikimap = ""
		for j = 4, #luatable[i] do
			wikimap = wikimap .. " " .. luatable[i][j]
		end
		wikitable = wikitable .. "\n| " .. frame:expandTemplate({ title = "map", args = { wikimap } })
	end
	wikitable = wikitable .. "\n|}"
	return wikitable
end

return p