Module:Uniform map

From Xenharmonic Wiki
Revision as of 02:38, 23 July 2023 by Fredg999 (talk | contribs) (Fixing more bugs...)
Jump to navigation Jump to search
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 (2)
Line Function Params
103 print_table (invokable) (frame)
108 _print_table (p, min, max)
Lua modules required (2)
Variable Module Functions used
getArgs Module:Arguments getArgs
u Module:Utils _log
index_of
_round_dec
signum
eval_num_arg

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


local getArgs = require('Module:Arguments').getArgs
local u = require('Module:Utils')
local 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}
map = {0, 0, 0}
lower = {0, 0 ,0}  -- List of smallest sizes that match a map for each prime
upper = {0, 0, 0}  -- List of largest sizes that match a map for each prime
pbi = 0            -- Index of the prime that defines the boundary
maptable = {}      -- Table of uniform maps with boundaries and wart notation

-- Find the minimum size that corresponds to a given map
function lowerbound(map)
	for i=1, #map do
		lower[i] = (map[i]-1/2)/u._log(primes[i])
		lowermax = math.max(unpack(lower))
	end
	return math.max(0, lowermax)
end

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

lb = lowerbound(map)  -- Minimum size for the current map
ub = upperbound(map)  -- Maximum size for the current map

-- Find the p-limit just intonation point (JIP) corresponding to a given size
function JIP(size, p)
	JIP_table = {}
	for i=1, u.index_of(primes, p) do
		JIP_table[i] = size*u._log(primes[i])
	end
	return JIP_table
end

-- Find the p-limit simple map corresponding to a given size
function simple_map(size, p)
	simple_map_table = {}
	for i=1, u.index_of(primes, p) do
		simple_map_table[i] = u._round_dec(size*u._log(primes[i]))
	end
	return simple_map_table
end

-- Find the wart notation corresponding to a given map
function wart(map)
	edo = map[1]
	simple_map_edo = simple_map(edo, primes[#map])
	JIP_edo = JIP(edo, primes[#map])
	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'}
	wart_notation = edo
	for i=2, #map do
		-- direction is 1 if current harmonic mapped flatter than just, otherwise 0
		direction = math.ceil(JIP_edo[i]-simple_map_edo[i])
		difference = map[i]-simple_map_edo[i]
		if difference ~= 0 then
			number_warts = (2*math.abs(difference)+(u.signum((-1)^direction*difference)-1)/2)
			for j=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
function make_table(p, min, max)
	maptable = {}                          -- Reset table
	for i=1, u.index_of(primes, p) do
		map[i] = 0                         -- Reset to p-limit null map
		lower[i] = 0
		upper[i] = 0
	end
	map = simple_map(min, p)               -- Set p-limit map for minimum size
	lb = lowerbound(map)                   -- Update minimum size for new map
	ub = upperbound(map)                   -- Update maximum size for new map
	row = {'Min. size', 'Max. size', '[[Wart notation]]'}
	for i=1, #map do
		table.insert(row, primes[i])
	end
	table.insert(maptable, row)
	while lb < max do
		row = {string.format("%.4f", lb), string.format("%.4f", ub), wart(map)}
		for j=1, #map do
			table.insert(row, map[j])
		end
		table.insert(maptable, row)
		map[pbi] = map[pbi] + 1
		lb = lowerbound(map)
		ub = upperbound(map)
	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)
	return p._print_table(args[1], args[2], args[3])
end

function p._print_table(p, min, max)
	if u.index_of(primes, u.eval_num_arg(p, 5)) == nil then
		p = 5                              -- Default to 5-limit
	end
	luatable = make_table(p, u.eval_num_arg(min, 11.5), u.eval_num_arg(max, 12.5))
	wikitable = string.format('{| class="wikitable"\n|+ %d-limit [[uniform map]]s between %f and %f', p, 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
		wikitable = wikitable .. '\n| {{map|'
		for j=1, #map do
			wikitable = wikitable .. ' ' .. luatable[i][j+3]
		end
		wikitable = wikitable .. '}}'
	end
	wikitable = wikitable .. '\n|}'
    return print(wikitable)
end

return p