Module:Interval table: Difference between revisions

From Xenharmonic Wiki
Jump to navigation Jump to search
Quick fix to unify the precision of cent values
Swap "approximte ratios" and "ups and downs notation" columns
Line 5: Line 5:
local ET = require("Module:ET")
local ET = require("Module:ET")


-- Gets mapping of a monzo in a val
-- Gets mapping of a monzo in a val
local function mapping(monzo, val)
local function mapping(monzo, val)
local result = 0
local result = 0
Line 94: Line 94:


wikitext = t_head ..  
wikitext = t_head ..  
"! Steps\n"..  
"! Steps\n" ..  
"! Cents\n"
"! Cents\n" ..
"! Approximate Ratios\n"
if rat.eq(et.equave, 2) then
if rat.eq(et.equave, 2) then
if dual_fifth then
if dual_fifth then
Line 114: Line 115:
end
end
end
end
 
wikitext = wikitext .. "! Approximate Ratios\n"
 
if #additional_split > 0 then
if #additional_split > 0 then
for i = 1, #additional_split[1] do
for i = 1, #additional_split[1] do
Line 127: Line 126:
wikitext = wikitext .. "|" .. i .. "\n"
wikitext = wikitext .. "|" .. i .. "\n"
wikitext = wikitext .. "|" .. utils._round_dec(ET.cents(et, i), 3) .. "\n"
wikitext = wikitext .. "|" .. utils._round_dec(ET.cents(et, i), 3) .. "\n"
if rat.eq(et.equave, 2) then
if dual_fifth then
wikitext = wikitext .. "|" .. ud_note(et, dual_flat_fifth, i) .. "\n"
wikitext = wikitext .. "|" .. ud_note(et, dual_sharp_fifth, i) .. "\n"
else
wikitext = wikitext .. "|" .. ud_note(et, fifth, i) .. "\n"
end
end
wikitext = wikitext .. "|"
wikitext = wikitext .. "|"
for j = 1, #ratios_list do
for j = 1, #ratios_list do
-- Go through all ratios.
-- Go through all ratios.
-- If they are mapped to the current step in the ET's patent val and <2/5 edo step error,
-- If they are mapped to the current step in the ET's patent val and < 2/5 edostep error,
-- add to approximate ratios column.
-- add to approximate ratios column.
local t = mapping(rat.new(ratios_list[j][1], ratios_list[j][2]), patent_val)
local t = mapping(rat.new(ratios_list[j][1], ratios_list[j][2]), patent_val)
Line 149: Line 140:
end
end
end
end
if rat.eq(et.equave, 2) then
if dual_fifth then
wikitext = wikitext .. "|" .. ud_note(et, dual_flat_fifth, i) .. "\n"
wikitext = wikitext .. "|" .. ud_note(et, dual_sharp_fifth, i) .. "\n"
else
wikitext = wikitext .. "|" .. ud_note(et, fifth, i) .. "\n"
end
end
-- ???
if wikitext:sub(-1, -1) == "|" then
if wikitext:sub(-1, -1) == "|" then
wikitext = wikitext .. "\n"
wikitext = wikitext .. "\n"

Revision as of 09:22, 27 June 2024

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

This module automatically generates a table of intervals for an equal-step tuning, showing which just intervals are approximated relatively accurately.

Introspection summary for Module:Interval table 
Functions provided (1)
Line Function Params
56 interval_table (invokable) (frame)
Lua modules required (4)
Variable Module Functions used
ET Module:ET parse
approximate
cents
rat Module:Rational max_prime
new
cents
eq
ud Module:Ups and downs notation get_note_names_table
utils Module:Utils _gcd
table_contains
_round_dec
_log

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


local p = {}
local utils = require("Module:Utils")
local rat = require("Module:Rational")
local ud = require("Module:Ups and downs notation")
local ET = require("Module:ET")

-- Gets mapping of a monzo in a val
local function mapping(monzo, val)
	local result = 0
	for k, _ in pairs(val) do
		result = result + val[k] * (monzo[k] or 0)
	end
	return result
end

-- Generates list of ratios up to a max numerator & denominator, max ratio size, and prime limit
local function get_ratios_list(max_nd, max_size, prime_limit)
	local ratios = {}
	local ratio_strings = {}
	for i = 1, max_nd do
		for j = 1, max_nd do
			local t = i / utils._gcd(i, j) .. "/" .. j / utils._gcd(i, j)
			if
				(i / j) >= 1
				and (i / j) <= max_size
				and rat.max_prime(rat.new (i, j)) <= prime_limit
				and not utils.table_contains(ratio_strings, t)
			then
				ratios[#ratios + 1] = { i / utils._gcd(i, j), j / utils._gcd(i, j) }
				ratio_strings[#ratio_strings + 1] = t
			end
		end
	end

	return ratios
end

-- Utility fuunction to get specific note name with ud.get_note_names_table
-- (this is essentially what "Template:Ups and downs note name" does)
local function ud_note(et, fifth, step)
	return table.concat(ud.get_note_names_table(et, fifth)[step], ", "):sub(0, -1)
end

-- ???
local function mysplit(inputstr, sep)
	if sep == nil then
		sep = "%s"
	end
	local t = {}
	for str in string.gmatch(inputstr, "([^" .. sep .. "]+)") do
		table.insert(t, str)
	end
	return t
end

function p.interval_table(frame)
	local additional = frame.args["additional"] or ""
	local additional_split = mysplit(additional, "\n")
	for i = 1, #additional_split do
		additional_split[i] = mysplit(additional_split[i], ";")
	end
	local tuning = frame.args["tuning"]
	local et = ET.parse(tuning) or ET.parse("12edo")
	local patent_val = {
		[2] = ET.approximate(et, 2),
		[3] = ET.approximate(et, 3),
		[5] = ET.approximate(et, 5),
		[7] = ET.approximate(et, 7),
		[11] = ET.approximate(et, 11),
		[13] = ET.approximate(et, 13),
		[17] = ET.approximate(et, 17),
		[19] = ET.approximate(et, 19),
		[23] = ET.approximate(et, 23),
		[29] = ET.approximate(et, 29),
		[31] = ET.approximate(et, 31),
		[37] = ET.approximate(et, 37),
		[41] = ET.approximate(et, 41),
		[43] = ET.approximate(et, 43),
		[47] = ET.approximate(et, 47),
	} -- NOTE: indices are prime numbers

	local t_head = '{| class="wikitable center-1 right-2"\n'
	if et.size > 72 then
		t_head = '{| class="wikitable center-1 right-2 mw-collapsible mw-collapsed"\n'
	end
	local fifth = patent_val[3] - patent_val[2]
	local fifth_error = ET.cents(et, fifth) - rat.cents(rat.new(3, 2))
	local dual_fifth = math.abs(fifth_error) > (400 / et.size)
	local dual_flat_fifth = ET.approximate(et, 3 / 2, -1)
	local dual_sharp_fifth = ET.approximate(et, 3 / 2, 1)

	-- List of all 13-limit ratios with numerator and denominator <= 81 and in the range 1/1 - 5/1
	local ratios_list = get_ratios_list(81, 5, 13)

	wikitext = t_head .. 
	"! Steps\n" .. 
	"! Cents\n" ..
	"! Approximate Ratios\n"
	if rat.eq(et.equave, 2) then
		if dual_fifth then
			wikitext = wikitext
				.. "! [[Ups and downs notation|Ups and Downs Notation]]<br>(Dual Flat Fifth "
				.. dual_flat_fifth
				.. "\\"
				.. et.size
				.. ")\n"
			wikitext = wikitext
				.. "! [[Ups and downs notation|Ups and Downs Notation]]<br>(Dual Sharp Fifth "
				.. dual_sharp_fifth
				.. "\\"
				.. et.size
				.. ")\n"
		else
			wikitext = wikitext .. "! [[Ups and downs notation|Ups and Downs Notation]]\n"
		end
	end
	
	if #additional_split > 0 then
		for i = 1, #additional_split[1] do
			wikitext = wikitext .. " ! " .. additional_split[1][i] .. "\n"
		end
	end

	for i = 0, et.size do
		wikitext = wikitext .. "|-\n"
		wikitext = wikitext .. "|" .. i .. "\n"
		wikitext = wikitext .. "|" .. utils._round_dec(ET.cents(et, i), 3) .. "\n"
		wikitext = wikitext .. "|"
		for j = 1, #ratios_list do
			-- Go through all ratios.
			-- If they are mapped to the current step in the ET's patent val and < 2/5 edostep error,
			-- add to approximate ratios column.
			local t = mapping(rat.new(ratios_list[j][1], ratios_list[j][2]), patent_val)
			if
				t == i
				and math.abs(ET.cents(et, i) - utils._log(ratios_list[j][1] / ratios_list[j][2], 2) * 1200)
					< (1200 / (2.5 * et.size))
			then
				wikitext = wikitext .. "[[" .. ratios_list[j][1] .. "/" .. ratios_list[j][2] .. "]], "
			end
		end
		if rat.eq(et.equave, 2) then
			if dual_fifth then
				wikitext = wikitext .. "|" .. ud_note(et, dual_flat_fifth, i) .. "\n"
				wikitext = wikitext .. "|" .. ud_note(et, dual_sharp_fifth, i) .. "\n"
			else
				wikitext = wikitext .. "|" .. ud_note(et, fifth, i) .. "\n"
			end
		end
		
		-- ???
		if wikitext:sub(-1, -1) == "|" then
			wikitext = wikitext .. "\n"
		else
			wikitext = wikitext:sub(0, -3) .. "\n"
		end
		if (i + 2) <= #additional_split then
			for j = 1, #additional_split[i + 2] do
				wikitext = wikitext .. "|" .. additional_split[i + 2][j] .. "\n"
			end
		end
	end

	wikitext = wikitext .. "|}"

	return wikitext
end

return p