Module:JI ratios in ED

From Xenharmonic Wiki
Revision as of 00:02, 23 January 2024 by Ganaram inukshuk (talk | contribs)
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:JI ratios in ED.
Module:JI ratios in ED is deprecated and has no replacement. Further use of this module is not advised. This module is kept for historical purposes and should not be deleted.
Introspection summary for Module:JI ratios in ED 
Functions provided (4)
Line Function Params
8 find_ratios_in_ed_by_primes (ed, primes, equave, tenney_height, denominator_limit)
90 parse_ed (unparsed)
98 parse_equave (unparsed)
115 ji_ratios_in_ed_frame (invokable) (frame)
Lua modules required (5)
Variable Module Functions used
interval Module:Interval dependency not used
jiraf Module:JI ratio finder find_candidate_ratios
filter_ratios_by_range
filter_ratios_by_prime_limit
filter_ratios_by_harmonic_class
filter_ratios_by_complement_agnostic_tenney_height
filter_exact_ratio
ratios_to_text_with_error
rat Module:Rational new
cents
as_ratio
parse
tip Module:Template input parse parse_numeric_entries
utils Module:Utils dependency not used

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


local utils = require('Module:Utils')
local interval = require('Module:Interval')
local rat = require('Module:Rational')
local jiraf = require('Module:JI ratio finder')
local tip = require('Module:Template input parse')
local p = {}

function p.find_ratios_in_ed_by_primes(ed, primes, equave, tenney_height, denominator_limit)
	local ed = ed or 12
	local primes = primes or { 3, 5, 7, 11, 13, 17, 19 }
	local equave = equave or rat.new(2, 1)
	local tenney_height = tenney_height or 10
	local denominator_limit = denominator_limit or 99
	
	local equave_in_cents = rat.cents(equave)
	local tolerance = equave_in_cents / ed * 0.4
	
	-- Find candidate ratios; filter later
	local max_prime = primes[#primes]
	local candidate_ratios = jiraf.find_candidate_ratios(equave_in_cents, denominator_limit, max_prime)
	
	-- Equave as text
	local equave_as_text = rat.as_ratio(equave) 
	if equave_as_text == "2/1" then
		equave_as_text = "edo"
	elseif equave_as_text == "3/1" then
		equave_as_text = "edt"
	elseif equave_as_text == "3/2" then
		equave_as_text = "edf"
	end
	
	-- Build table headers
	local result = string.format('{| class="wikitable center-all"\n')
	result = result .. string.format('|+ Intervals of %d%s\n', ed, equave_as_text)
	result = result .. string.format('|-\n')
	result = result .. string.format('! rowspan="2" | [[Degree]]\n')
	result = result .. string.format('! rowspan="2" | [[Cent]]s\n')
	result = result .. string.format('! colspan="%d" | Approximated [[JI]] intervals ([[error]] in cents)\n', #primes)
	result = result .. string.format('|-\n')
	
	-- Add table headers for prime limits (technically harmonic classes)
	for i = 1, #primes do
		local current_prime = primes[i]	
		result = result .. string.format('! [[%d-limit]]\n', current_prime)
	end
	result = result .. string.format('|-\n')
	
	-- Build the rows for each edstep, showing ratios by limit
	for i = 1, ed + 1 do
		local edstep = i - 1
		local edstep_in_cents = (edstep / ed) * equave_in_cents
		local filtered_ratios = jiraf.filter_ratios_by_range(candidate_ratios, edstep_in_cents - tolerance, edstep_in_cents + tolerance)
		
		result = result .. string.format('| %d\n', edstep)
		result = result .. string.format('| %.3f\n', edstep_in_cents)
		
		for j = 1, #primes do
			local current_prime = primes[j]
			
			-- The first column filters by prime limit
			-- Successive columns are filered by harmonic class
			local prime_filtered_ratios = {}
			if j == 1 then
				prime_filtered_ratios = jiraf.filter_ratios_by_prime_limit(filtered_ratios, current_prime)
			else
				prime_filtered_ratios = jiraf.filter_ratios_by_harmonic_class(filtered_ratios, current_prime)
			end
			
			-- Filter ratios by complement-agnostic tenney height
			prime_filtered_ratios = jiraf.filter_ratios_by_complement_agnostic_tenney_height(prime_filtered_ratios, tenney_height, equave)
			
			-- Filter ratios by exact cent value
			local exact_ratio = jiraf.filter_exact_ratio(prime_filtered_ratios, edstep_in_cents)
			if exact_ratio ~= nil then
				prime_filtered_ratios = { exact_ratio }
			end
			
			-- Add ratios to cells
			local ratios_as_text = jiraf.ratios_to_text_with_error(prime_filtered_ratios, edstep_in_cents, "<br>", true)
			result = result .. string.format('| %s\n', ratios_as_text)
		end
		
		result = result .. string.format('|-\n')
	end
	
	result = result .. string.format('|}\n')
	return result
end

function p.parse_ed(unparsed)
	local unparsed = unparsed or "12edo"
	
	local ed = tonumber(unparsed) or unparsed:match('(%d+)ed')

	return ed
end

function p.parse_equave(unparsed)
	local unparsed = unparsed or "10ed4"
	
	local equave_unparsed = ""
	if string.match(unparsed, "edo") or tonumber(unparsed) ~= nil then
		equave_unparsed = "2/1"
	elseif string.match(unparsed, "edt") then
		equave_unparsed = "3/1"
	elseif string.match(unparsed, "edf") then
		equave_unparsed = "3/2"
	else
		equave_unparsed = unparsed:match('[%d]+ed([%d]+/[%d]+)') or unparsed:match('[%d]+ed([%d]+)')
	end
	
	return rat.parse(equave_unparsed)
end

function p.ji_ratios_in_ed_frame(frame)
	
	local ed = p.parse_ed(frame.args["ED"])
	local equave = p.parse_equave(frame.args["ED"])

	local primes = { 3, 5, 7, 11, 13 }
	if string.len(frame.args["Primes"]) > 0 then
		primes = tip.parse_numeric_entries(frame.args["Primes"], ',')
	end
	
	local tenney_height = tonumber(frame.args["Tenney Height"]) or 10
	local denominator_limit = tonumber(frame.args["Denominator Limit"]) or 99
	
	local result = p.find_ratios_in_ed_by_primes(ed, primes, equave, tenney_height, denominator_limit)
	
	return result
	
end

return p