Module:Uniform map: Difference between revisions

From Xenharmonic Wiki
Jump to navigation Jump to search
m ...
m Fix luatable size
Line 120: Line 120:
end
end
wikitable = wikitable .. '\n| {{map|'
wikitable = wikitable .. '\n| {{map|'
for j=4, #luatable do
for j=4, #luatable[i] do
wikitable = wikitable .. ' ' .. luatable[i][j]
wikitable = wikitable .. ' ' .. luatable[i][j]
end
end

Revision as of 03:45, 23 July 2023

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
11 lowerbound (map)
21 upperbound (map)
32 JIP (size, prime)
41 simple_map (size, prime)
50 wart (map)
71 make_table (prime, min, max)
101 print_table (invokable) (frame)
106 _print_table (prime, 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 = {}

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}
p.lower = {0, 0 ,0}  -- List of smallest sizes that match a map for each prime
p.upper = {0, 0, 0}  -- List of largest sizes that match a map for each prime
p.pbi = 0            -- Index of the prime that defines the boundary

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

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

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

-- Find the p-limit simple map corresponding to a given size
function p.simple_map(size, prime)
	local simple_map_table = {}
	for i=1, u.index_of(p.primes, prime) do
		simple_map_table[i] = u._round_dec(size*u._log(p.primes[i]))
	end
	return simple_map_table
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, p.primes[#map])
	local JIP_edo = p.JIP(edo, p.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
	for i=2, #map do
		-- direction is 1 if current harmonic mapped flatter than just, otherwise 0
		local direction = math.ceil(JIP_edo[i]-simple_map_edo[i])
		local 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 (but could potentially be used standalone for raw data with headers)
function p.make_table(prime, min, max)
	local map = {}
	local maptable = {}                     -- Table of uniform maps with boundaries and wart notation
	for i=1, u.index_of(p.primes, prime) do
		map[i] = 0                          -- Reset to p-limit null map
		p.lower[i] = 0
		p.upper[i] = 0
	end
	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
	table.insert(maptable, row)
	while lb < max do
		row = {string.format("%.4f", lb), string.format("%.4f", ub), p.wart(map)}
		for j=1, #map do
			table.insert(row, map[j])
		end
		table.insert(maptable, row)
		map[pbi] = map[pbi] + 1
		lb = p.lowerbound(map)
		ub = p.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(prime, min, max)
	if u.index_of(p.primes, u.eval_num_arg(prime, 5)) == nil then
		prime = 5                          -- Default to 5-limit
	end
	luatable = p.make_table(prime, 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', 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
		wikitable = wikitable .. '\n| {{map|'
		for j=4, #luatable[i] do
			wikitable = wikitable .. ' ' .. luatable[i][j]
		end
		wikitable = wikitable .. '}}'
	end
	wikitable = wikitable .. '\n|}'
    return print(wikitable)
end

return p