Module:JI ratios in ED: Difference between revisions
Jump to navigation
Jump to search
Denominator limit -> integer limit; tolerance will max out at +/- 40 cents |
Cleanup code |
||
| Line 24: | Line 24: | ||
-- Helper function | -- Helper function | ||
-- Converts a set of primes | -- Converts a set of primes (typically a prime subgroup) into text | ||
function p. | function p.subgroup_as_text(primes) | ||
local primes = primes or { 2, 3, 5, 7 } | local primes = primes or { 2, 3, 5, 7 } | ||
| Line 40: | Line 40: | ||
-- Helper function | -- Helper function | ||
-- | -- Creates the non-header cells in the table | ||
function p.ji_ratio_in_ed_content_cells(steps, equave, candidate_ratios, primes) | |||
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 primes = primes or { 2, 3 | -- Calculate equave and tolerance | ||
local | -- Tolerance is +/- 40 cents or 40% of a step, whichever is smaller. | ||
local equave_in_cents = rat.cents(equave) | |||
local tolerance = math.min(equave_in_cents / steps * 0.4, 40) | |||
local | -- 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) | |||
-- Filter ratios by whether they're within the current step | |||
local filtered_ratios = jiraf.filter_ratios_by_range(candidate_ratios, step_in_cents - tolerance, step_in_cents + tolerance) | |||
-- 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_with_error(prime_filtered_ratios, step_in_cents, "<br>", true) | |||
result = result .. string.format('| %s\n', ratios_as_text) | |||
end | |||
result = result .. string.format('|-\n') | |||
end | end | ||
return result | |||
return | |||
end | end | ||
-- | -- Main function variant for prime limit | ||
function p. | function p.ji_ratios_in_ed_by_prime_limit(input_et, int_limit, prime_limit, tenney_height) | ||
local input_et = input_et or et.parse(" | local input_et = input_et or et.parse("12edo") | ||
local | local prime_limit = 7 | ||
local tenney_height = tenney_height or 10 | local tenney_height = tenney_height or 10 | ||
local int_limit = int_limit or 99 | local int_limit = int_limit or 99 | ||
| Line 79: | Line 106: | ||
local equave_in_cents = rat.cents(equave) | local equave_in_cents = rat.cents(equave) | ||
local tolerance = math.min(equave_in_cents / steps * 0.4, 40) | local tolerance = math.min(equave_in_cents / steps * 0.4, 40) | ||
-- 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) | |||
local | |||
-- Build table headers | -- Build table headers | ||
local result = string.format('{| class="wikitable center-all"\n') | local result = string.format('{| class="wikitable center-all"\n') | ||
result = result .. string.format('|+ Intervals of %s (as a % | result = result .. string.format('|+ Intervals of %s (as a %d-limit temperament)\n', et_as_string, prime_limit) | ||
result = result .. string.format('|-\n') | result = result .. string.format('|-\n') | ||
result = result .. string.format('! rowspan="2" | [[Degree]]\n') | result = result .. string.format('! rowspan="2" | [[Degree]]\n') | ||
| Line 96: | Line 126: | ||
result = result .. string.format('|-\n') | result = result .. string.format('|-\n') | ||
-- Add table | -- Add rest of table | ||
result = result .. p.ji_ratio_in_ed_content_cells(steps, equave, candidate_ratios, primes) | |||
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) | |||
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 | |||
-- 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 | end | ||
local et_as_string = et.as_string(input_et) | |||
-- Calculate equave and tolerance | |||
-- Tolerance is +/- 40 cents or 40% of a step, whichever is smaller. | |||
local equave_in_cents = rat.cents(equave) | |||
local tolerance = math.min(equave_in_cents / steps * 0.4, 40) | |||
-- 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 = string.format('{| class="wikitable center-all"\n') | |||
result = result .. string.format('|+ Intervals of %s (as a %s subgroup temperament)\n', et_as_string, subgroup_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') | result = result .. string.format('|-\n') | ||
-- | -- Add rest of table | ||
result = result .. p.ji_ratio_in_ed_content_cells(steps, equave, candidate_ratios, primes) | |||
result = result .. string.format('|}\n') | result = result .. string.format('|}\n') | ||
| Line 159: | Line 188: | ||
end | end | ||
local input_et = et.parse(input_et_unparsed) | 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 primes = | local primes = nil | ||
local temperament_type = "" | |||
if string.len(frame.args["Subgroup"]) > 0 then | if string.len(frame.args["Subgroup"]) > 0 then | ||
primes = tip.parse_numeric_entries(frame.args["Subgroup"], '.') or tip.parse_numeric_entries(frame.args["Subgroup"], ',') | primes = tip.parse_numeric_entries(frame.args["Subgroup"], '.') or tip.parse_numeric_entries(frame.args["Subgroup"], ',') | ||
temperament_type = "Subgroup" | |||
end | end | ||
if string.len(frame.args["Prime Limit"]) > 0 and string.len(frame.args["Subgroup"]) == 0 then | if string.len(frame.args["Prime Limit"]) > 0 and string.len(frame.args["Subgroup"]) == 0 then | ||
primes = | primes = tonumber(frame.args["Prime Limit"]) | ||
temperament_type = "Prime Limit" | |||
end | end | ||
local | local result = "" | ||
if temperament_type == "Subgroup" then | |||
result = p.find_ratios_in_ed_by_subgroup(input_et, primes, tenney_height, int_limit) | |||
elseif temperament_type == "Prime Limit" then | |||
result = p.find_ratios_in_ed_by_subgroup(input_et, primes, tenney_height, int_limit) | |||
end | |||
return result | return result | ||
Revision as of 06:32, 27 January 2024
- 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 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 et = require('Module:ET')
local p = {}
-- 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)
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 }
-- Calculate equave and tolerance
-- Tolerance is +/- 40 cents or 40% of a step, whichever is smaller.
local equave_in_cents = rat.cents(equave)
local tolerance = math.min(equave_in_cents / steps * 0.4, 40)
-- 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)
-- Filter ratios by whether they're within the current step
local filtered_ratios = jiraf.filter_ratios_by_range(candidate_ratios, step_in_cents - tolerance, step_in_cents + tolerance)
-- 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_with_error(prime_filtered_ratios, step_in_cents, "<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)
local input_et = input_et or et.parse("12edo")
local prime_limit = 7
local tenney_height = tenney_height or 10
local int_limit = int_limit or 99
-- 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 +/- 40 cents or 40% of a step, whichever is smaller.
local equave_in_cents = rat.cents(equave)
local tolerance = math.min(equave_in_cents / steps * 0.4, 40)
-- 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 = string.format('{| class="wikitable center-all"\n')
result = result .. string.format('|+ Intervals of %s (as a %d-limit temperament)\n', et_as_string, prime_limit)
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 rest of table
result = result .. p.ji_ratio_in_ed_content_cells(steps, equave, candidate_ratios, primes)
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)
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
-- 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 +/- 40 cents or 40% of a step, whichever is smaller.
local equave_in_cents = rat.cents(equave)
local tolerance = math.min(equave_in_cents / steps * 0.4, 40)
-- 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 = string.format('{| class="wikitable center-all"\n')
result = result .. string.format('|+ Intervals of %s (as a %s subgroup temperament)\n', et_as_string, subgroup_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 rest of table
result = result .. p.ji_ratio_in_ed_content_cells(steps, equave, candidate_ratios, primes)
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"]
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 primes = nil
local temperament_type = ""
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
if string.len(frame.args["Prime Limit"]) > 0 and string.len(frame.args["Subgroup"]) == 0 then
primes = tonumber(frame.args["Prime Limit"])
temperament_type = "Prime Limit"
end
local result = ""
if temperament_type == "Subgroup" then
result = p.find_ratios_in_ed_by_subgroup(input_et, primes, tenney_height, int_limit)
elseif temperament_type == "Prime Limit" then
result = p.find_ratios_in_ed_by_subgroup(input_et, primes, tenney_height, int_limit)
end
return result
end
return p