Module:JI ratios in ED: Difference between revisions
Jump to navigation
Jump to search
Created page with "local utils = require('Module:Utils') local interval = require('Module:Interval') local rat = require('Module:Rational') local jiraf = require('Module:JI ratio finder') local..." |
ArrowHead294 (talk | contribs) mNo edit summary |
||
| (79 intermediate revisions by 2 users not shown) | |||
| Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
local et = require("Module:ET") | |||
--local interval = require('Module:Harmonic entropy') | |||
local jiraf = require("Module:JI ratio finder") | |||
local | local rat = require("Module:Rational") | ||
local tip = require("Module:Template input parse") | |||
local utils = require("Module:Utils") | |||
local yesno = require("Module:Yesno") | |||
-- Helper function | |||
-- Given a prime limit, return an array of all primes between (and including) 2 | |||
-- and that limit | |||
-- EG, 7-limit becomes { 2, 3, 5, 7 } | |||
function p.primes_within_prime_limit(prime_limit) | |||
local prime_limit = prime_limit or 7 | |||
local | local primes = {} | ||
local | for i = 2, prime_limit do | ||
if utils.is_prime(i) then | |||
table.insert(primes, i) | |||
end | |||
end | |||
return primes | |||
end | |||
-- Helper function | |||
-- Converts a set of primes (typically a prime subgroup) into text | |||
function p.subgroup_as_text(primes) | |||
local primes = primes or { 2, 3, 5, 7 } | |||
local | local subgroup = "" | ||
for i = 1, #primes do | for i = 1, #primes do | ||
if i ~= #primes then | |||
subgroup = subgroup .. string.format("%d.", primes[i]) | |||
else | |||
subgroup = subgroup .. primes[i] | |||
end | |||
end | end | ||
return subgroup | |||
end | |||
-- Helper function | |||
-- Creates the non-header cells in the table | |||
function p.ji_ratio_in_ed_content_cells(steps, equave, candidate_ratios, primes, tolerance) | |||
local steps = steps or 12 | |||
local equave = equave or rat.new(2) | |||
local candidate_ratios = candidate_ratios or { rat.new(1), rat.new(2), rat.new(3, 2), rat.new(4, 3), rat.new (5, 4), rat.new (9, 7)} | |||
local primes = primes or { 2, 3, 7 } | |||
local tolerance = tolerance or 20 | |||
-- Build the rows for each | -- Calculate equave | ||
for i = 1, | local equave_in_cents = rat.cents(equave) | ||
local | |||
-- Build the rows for each step, showing ratios by limit | |||
local result = "" | |||
for i = 1, steps + 1 do | |||
local step = i - 1 | |||
result = result .. string.format( | -- Table headers | ||
result = result .. string.format( | local step_in_cents = (step / steps) * rat.cents(equave) | ||
result = result .. string.format("| %d\n", step) | |||
result = result .. string.format("| %.3f\n", step_in_cents) | |||
-- If this is the first or last step, only use the unison or equave | |||
-- respectively; otherwise, filter ratios by whether they're within the | |||
-- current step | |||
local filtered_ratios = {} | |||
if step == 0 then | |||
filtered_ratios = { rat.new(1) } | |||
elseif step == steps then | |||
filtered_ratios = { equave } | |||
else | |||
filtered_ratios = jiraf.filter_ratios_by_range(candidate_ratios, step_in_cents - tolerance, step_in_cents + tolerance) | |||
end | |||
-- Add ratios according to harmonic class | |||
for j = 1, #primes do | for j = 1, #primes do | ||
local current_prime = primes[j] | local current_prime = primes[j] | ||
local prime_filtered_ratios = jiraf.filter_ratios_by_harmonic_class(filtered_ratios, | -- For each prime, filter by harmonic class | ||
local ratios_as_text = jiraf.ratios_to_text(prime_filtered_ratios, ", | -- For the first column, filter by prime limit instead | ||
result = result .. string.format( | local prime_filtered_ratios = {} | ||
if j == 1 then | |||
prime_filtered_ratios = jiraf.filter_ratios_by_prime_limit(filtered_ratios, primes[j]) | |||
else | |||
prime_filtered_ratios = jiraf.filter_ratios_by_harmonic_class(filtered_ratios, primes[j]) | |||
end | |||
local ratios_as_text = jiraf.ratios_to_text(prime_filtered_ratios, "<br>", true) | |||
result = result .. string.format("| %s\n", ratios_as_text) | |||
end | end | ||
result = result .. string.format( | result = result .. string.format("|-\n") | ||
end | |||
return result | |||
end | |||
-- Main function variant for prime limit | |||
function p.ji_ratios_in_ed_by_prime_limit(input_et, int_limit, prime_limit, tenney_height, threshold) | |||
local input_et = input_et or et.parse("12edo") | |||
local prime_limit = prime_limit or 7 | |||
local tenney_height = tenney_height or 10 | |||
local int_limit = int_limit or 99 | |||
local threshold = threshold or 0.3 | |||
-- Get the number of divisions, equave, and et as text (eg edo, edt, etc) | |||
local steps = input_et["size"] | |||
local equave = input_et["equave"] | |||
if tonumber(equave) ~= nil then | |||
equave = rat.new(equave) | |||
end | |||
local et_as_string = et.as_string(input_et) | |||
-- Calculate equave and tolerance | |||
-- Tolerance is a percentage (threshold) of the step size | |||
local equave_in_cents = rat.cents(equave) | |||
local tolerance = equave_in_cents / steps * threshold | |||
-- Calculate candidate ratios | |||
-- Then filter based on whether their complements exceed the int limit | |||
-- Then filter candidate ratios by tenney height (excludes equave factors) | |||
local candidate_ratios = jiraf.find_candidate_ratios_within_prime_limit(equave_in_cents, int_limit, prime_limit) | |||
candidate_ratios = jiraf.filter_ratios_by_equave_complement_int_limit(candidate_ratios, int_limit, equave) | |||
candidate_ratios = jiraf.filter_ratios_by_no_equave_factors_tenney_height(candidate_ratios, tenney_height, equave) | |||
-- Get the primes | |||
local primes = p.primes_within_prime_limit(prime_limit) | |||
-- Build table headers | |||
local result = "{| class=\"wikitable center-all\"\n" | |||
.. "|+ style=\"font-size: 105%;\" | " | |||
.. string.format("Intervals of %s (as a %d-limit temperament)\n", et_as_string, prime_limit) | |||
.. "|-\n" | |||
.. "! rowspan=\"2\" | [[Degree]]\n" | |||
.. "! rowspan=\"2\" | [[Cent]]s\n" | |||
.. string.format("! colspan=\"%d\" | Approximated [[JI]] intervals\n", #primes) | |||
.. "|-\n" | |||
-- Build header cells for each prime limit | |||
for i = 1, #primes do | |||
result = result .. string.format("! [[%d-limit]]\n", primes[i]) | |||
end | end | ||
result = result .. string.format("|-\n") | |||
result = result .. string.format( | -- Add rest of table | ||
result = result .. p.ji_ratio_in_ed_content_cells(steps, equave, candidate_ratios, primes, tolerance) | |||
result = result .. string.format("|}\n") | |||
return result | return result | ||
end | end | ||
function p. | -- Main function variant for prime subgroup | ||
local | function p.ji_ratios_in_ed_by_prime_subgroup(input_et, int_limit, primes, tenney_height, threshold) | ||
local input_et = input_et or et.parse("12edo") | |||
local primes = primes or { 2, 3, 5, 11 } | |||
local tenney_height = tenney_height or 10 | |||
local int_limit = int_limit or 99 | |||
local threshold = threshold or 0.3 | |||
local | -- Get the number of divisions, equave, and et as text (eg edo, edt, etc) | ||
local steps = input_et["size"] | |||
local equave = input_et["equave"] | |||
if tonumber(equave) ~= nil then | |||
equave = rat.new(equave) | |||
end | |||
local et_as_string = et.as_string(input_et) | |||
local | -- Calculate equave and tolerance | ||
-- Tolerance is a percentage (threshold) of the step size | |||
local equave_in_cents = rat.cents(equave) | |||
local tolerance = equave_in_cents / steps * threshold | |||
-- Calculate candidate ratios | |||
-- Then filter based on whether their complements exceed the int limit | |||
-- Then filter candidate ratios by tenney height (excludes equave factors) | |||
local candidate_ratios = jiraf.find_candidate_ratios_within_subgroup(equave_in_cents, int_limit, primes) | |||
candidate_ratios = jiraf.filter_ratios_by_equave_complement_int_limit(candidate_ratios, int_limit, equave) | |||
candidate_ratios = jiraf.filter_ratios_by_no_equave_factors_tenney_height(candidate_ratios, tenney_height, equave) | |||
-- Get subgroup as text | |||
local subgroup_as_text = p.subgroup_as_text(primes) | |||
-- Build table headers | |||
local result = "{| class=\"wikitable center-all\"\n" | |||
.. "|+ style=\"font-size: 105%;\" | " | |||
.. string.format("Intervals of %s (as a %s subgroup temperament)\n", et_as_string, subgroup_as_text) | |||
.. "|-\n" | |||
.. "! rowspan=\"2\" | [[Degree]]\n" | |||
.. "! rowspan=\"2\" | [[Cent]]s\n" | |||
.. string.format("! colspan=\"%d\" | Approximated [[JI]] intervals\n", #primes) | |||
.. "|-\n" | |||
-- Build header cells for each prime limit | |||
for i = 1, #primes do | |||
result = result .. string.format("! [[%d-limit]]\n", primes[i]) | |||
end | end | ||
result = result .. "|-\n" | |||
-- Add rest of table | |||
result = result .. p.ji_ratio_in_ed_content_cells(steps, equave, candidate_ratios, primes, tolerance) | |||
result = result .. string.format("|}\n") | |||
return result | |||
end | end | ||
-- Wrapper function for primary function; to be called by template | |||
function p.ji_ratios_in_ed_frame(frame) | function p.ji_ratios_in_ed_frame(frame) | ||
-- Parse the ed; if it's just a number, interpret it as an edo | |||
local input_et_unparsed = frame.args["ED"] or 12 | |||
if tonumber(input_et_unparsed) ~= nil then | |||
input_et_unparsed = input_et_unparsed .. "edo" | |||
end | |||
local input_et = et.parse(input_et_unparsed) | |||
local | local tenney_height = tonumber(frame.args["Tenney Height"]) or 10 | ||
local | local int_limit = tonumber(frame.args["Integer Limit"]) or 99 | ||
local threshold = tonumber(frame.args["Threshold"]) or 0.3 | |||
local primes = tonumber(frame.args["Prime Limit"]) or 5 | |||
local temperament_type = "Prime Limit" | |||
if string.len(frame.args["Subgroup"]) > 0 then | |||
primes = tip.parse_numeric_entries(frame.args["Subgroup"], ".") or tip.parse_numeric_entries(frame.args["Subgroup"], ",") | |||
temperament_type = "Subgroup" | |||
end | |||
local | local result = "" | ||
if temperament_type == "Subgroup" then | |||
result = p.ji_ratios_in_ed_by_prime_subgroup(input_et, int_limit, primes, tenney_height, threshold) | |||
elseif temperament_type == "Prime Limit" then | |||
result = p.ji_ratios_in_ed_by_prime_limit(input_et, int_limit, primes, tenney_height, threshold) | |||
end | |||
local | local debugg = yesno(frame.args["debug"]) | ||
if debugg == true then | |||
result = "<syntaxhighlight lang=\"wikitext\">" .. result .. "</syntaxhighlight>" | |||
end | |||
return frame:preprocess(result) | |||
end | end | ||
return p | return p | ||
Latest revision as of 12:14, 1 June 2025
- 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 | |||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
| ||||||||||||||||||||||||||||||||||||||||||
No function descriptions were provided. The Lua code may have further information.
local p = {}
local et = require("Module:ET")
--local interval = require('Module:Harmonic entropy')
local jiraf = require("Module:JI ratio finder")
local rat = require("Module:Rational")
local tip = require("Module:Template input parse")
local utils = require("Module:Utils")
local yesno = require("Module:Yesno")
-- Helper function
-- Given a prime limit, return an array of all primes between (and including) 2
-- and that limit
-- EG, 7-limit becomes { 2, 3, 5, 7 }
function p.primes_within_prime_limit(prime_limit)
local prime_limit = prime_limit or 7
local primes = {}
for i = 2, prime_limit do
if utils.is_prime(i) then
table.insert(primes, i)
end
end
return primes
end
-- Helper function
-- Converts a set of primes (typically a prime subgroup) into text
function p.subgroup_as_text(primes)
local primes = primes or { 2, 3, 5, 7 }
local subgroup = ""
for i = 1, #primes do
if i ~= #primes then
subgroup = subgroup .. string.format("%d.", primes[i])
else
subgroup = subgroup .. primes[i]
end
end
return subgroup
end
-- Helper function
-- Creates the non-header cells in the table
function p.ji_ratio_in_ed_content_cells(steps, equave, candidate_ratios, primes, tolerance)
local steps = steps or 12
local equave = equave or rat.new(2)
local candidate_ratios = candidate_ratios or { rat.new(1), rat.new(2), rat.new(3, 2), rat.new(4, 3), rat.new (5, 4), rat.new (9, 7)}
local primes = primes or { 2, 3, 7 }
local tolerance = tolerance or 20
-- Calculate equave
local equave_in_cents = rat.cents(equave)
-- Build the rows for each step, showing ratios by limit
local result = ""
for i = 1, steps + 1 do
local step = i - 1
-- Table headers
local step_in_cents = (step / steps) * rat.cents(equave)
result = result .. string.format("| %d\n", step)
result = result .. string.format("| %.3f\n", step_in_cents)
-- If this is the first or last step, only use the unison or equave
-- respectively; otherwise, filter ratios by whether they're within the
-- current step
local filtered_ratios = {}
if step == 0 then
filtered_ratios = { rat.new(1) }
elseif step == steps then
filtered_ratios = { equave }
else
filtered_ratios = jiraf.filter_ratios_by_range(candidate_ratios, step_in_cents - tolerance, step_in_cents + tolerance)
end
-- Add ratios according to harmonic class
for j = 1, #primes do
local current_prime = primes[j]
-- For each prime, filter by harmonic class
-- For the first column, filter by prime limit instead
local prime_filtered_ratios = {}
if j == 1 then
prime_filtered_ratios = jiraf.filter_ratios_by_prime_limit(filtered_ratios, primes[j])
else
prime_filtered_ratios = jiraf.filter_ratios_by_harmonic_class(filtered_ratios, primes[j])
end
local ratios_as_text = jiraf.ratios_to_text(prime_filtered_ratios, "<br>", true)
result = result .. string.format("| %s\n", ratios_as_text)
end
result = result .. string.format("|-\n")
end
return result
end
-- Main function variant for prime limit
function p.ji_ratios_in_ed_by_prime_limit(input_et, int_limit, prime_limit, tenney_height, threshold)
local input_et = input_et or et.parse("12edo")
local prime_limit = prime_limit or 7
local tenney_height = tenney_height or 10
local int_limit = int_limit or 99
local threshold = threshold or 0.3
-- Get the number of divisions, equave, and et as text (eg edo, edt, etc)
local steps = input_et["size"]
local equave = input_et["equave"]
if tonumber(equave) ~= nil then
equave = rat.new(equave)
end
local et_as_string = et.as_string(input_et)
-- Calculate equave and tolerance
-- Tolerance is a percentage (threshold) of the step size
local equave_in_cents = rat.cents(equave)
local tolerance = equave_in_cents / steps * threshold
-- Calculate candidate ratios
-- Then filter based on whether their complements exceed the int limit
-- Then filter candidate ratios by tenney height (excludes equave factors)
local candidate_ratios = jiraf.find_candidate_ratios_within_prime_limit(equave_in_cents, int_limit, prime_limit)
candidate_ratios = jiraf.filter_ratios_by_equave_complement_int_limit(candidate_ratios, int_limit, equave)
candidate_ratios = jiraf.filter_ratios_by_no_equave_factors_tenney_height(candidate_ratios, tenney_height, equave)
-- Get the primes
local primes = p.primes_within_prime_limit(prime_limit)
-- Build table headers
local result = "{| class=\"wikitable center-all\"\n"
.. "|+ style=\"font-size: 105%;\" | "
.. string.format("Intervals of %s (as a %d-limit temperament)\n", et_as_string, prime_limit)
.. "|-\n"
.. "! rowspan=\"2\" | [[Degree]]\n"
.. "! rowspan=\"2\" | [[Cent]]s\n"
.. string.format("! colspan=\"%d\" | Approximated [[JI]] intervals\n", #primes)
.. "|-\n"
-- Build header cells for each prime limit
for i = 1, #primes do
result = result .. string.format("! [[%d-limit]]\n", primes[i])
end
result = result .. string.format("|-\n")
-- Add rest of table
result = result .. p.ji_ratio_in_ed_content_cells(steps, equave, candidate_ratios, primes, tolerance)
result = result .. string.format("|}\n")
return result
end
-- Main function variant for prime subgroup
function p.ji_ratios_in_ed_by_prime_subgroup(input_et, int_limit, primes, tenney_height, threshold)
local input_et = input_et or et.parse("12edo")
local primes = primes or { 2, 3, 5, 11 }
local tenney_height = tenney_height or 10
local int_limit = int_limit or 99
local threshold = threshold or 0.3
-- Get the number of divisions, equave, and et as text (eg edo, edt, etc)
local steps = input_et["size"]
local equave = input_et["equave"]
if tonumber(equave) ~= nil then
equave = rat.new(equave)
end
local et_as_string = et.as_string(input_et)
-- Calculate equave and tolerance
-- Tolerance is a percentage (threshold) of the step size
local equave_in_cents = rat.cents(equave)
local tolerance = equave_in_cents / steps * threshold
-- Calculate candidate ratios
-- Then filter based on whether their complements exceed the int limit
-- Then filter candidate ratios by tenney height (excludes equave factors)
local candidate_ratios = jiraf.find_candidate_ratios_within_subgroup(equave_in_cents, int_limit, primes)
candidate_ratios = jiraf.filter_ratios_by_equave_complement_int_limit(candidate_ratios, int_limit, equave)
candidate_ratios = jiraf.filter_ratios_by_no_equave_factors_tenney_height(candidate_ratios, tenney_height, equave)
-- Get subgroup as text
local subgroup_as_text = p.subgroup_as_text(primes)
-- Build table headers
local result = "{| class=\"wikitable center-all\"\n"
.. "|+ style=\"font-size: 105%;\" | "
.. string.format("Intervals of %s (as a %s subgroup temperament)\n", et_as_string, subgroup_as_text)
.. "|-\n"
.. "! rowspan=\"2\" | [[Degree]]\n"
.. "! rowspan=\"2\" | [[Cent]]s\n"
.. string.format("! colspan=\"%d\" | Approximated [[JI]] intervals\n", #primes)
.. "|-\n"
-- Build header cells for each prime limit
for i = 1, #primes do
result = result .. string.format("! [[%d-limit]]\n", primes[i])
end
result = result .. "|-\n"
-- Add rest of table
result = result .. p.ji_ratio_in_ed_content_cells(steps, equave, candidate_ratios, primes, tolerance)
result = result .. string.format("|}\n")
return result
end
-- Wrapper function for primary function; to be called by template
function p.ji_ratios_in_ed_frame(frame)
-- Parse the ed; if it's just a number, interpret it as an edo
local input_et_unparsed = frame.args["ED"] or 12
if tonumber(input_et_unparsed) ~= nil then
input_et_unparsed = input_et_unparsed .. "edo"
end
local input_et = et.parse(input_et_unparsed)
local tenney_height = tonumber(frame.args["Tenney Height"]) or 10
local int_limit = tonumber(frame.args["Integer Limit"]) or 99
local threshold = tonumber(frame.args["Threshold"]) or 0.3
local primes = tonumber(frame.args["Prime Limit"]) or 5
local temperament_type = "Prime Limit"
if string.len(frame.args["Subgroup"]) > 0 then
primes = tip.parse_numeric_entries(frame.args["Subgroup"], ".") or tip.parse_numeric_entries(frame.args["Subgroup"], ",")
temperament_type = "Subgroup"
end
local result = ""
if temperament_type == "Subgroup" then
result = p.ji_ratios_in_ed_by_prime_subgroup(input_et, int_limit, primes, tenney_height, threshold)
elseif temperament_type == "Prime Limit" then
result = p.ji_ratios_in_ed_by_prime_limit(input_et, int_limit, primes, tenney_height, threshold)
end
local debugg = yesno(frame.args["debug"])
if debugg == true then
result = "<syntaxhighlight lang=\"wikitext\">" .. result .. "</syntaxhighlight>"
end
return frame:preprocess(result)
end
return p