Module:JI ratios: Difference between revisions
m todo |
Rename functions; combine tenney height and int limit (plus complements-only, a new unimplemented search arg) into a table of search args; will momentarily break dependent templates |
||
| Line 3: | Line 3: | ||
local tip = require("Module:Template input parse") | local tip = require("Module:Template input parse") | ||
local med = require("Module:Mediants") | local med = require("Module:Mediants") | ||
local yesno = require("Module:Yesno") | |||
p = {} | p = {} | ||
| Line 26: | Line 27: | ||
-- optional. If omitted, tenney height defaults to infinity. | -- optional. If omitted, tenney height defaults to infinity. | ||
local DEFAULT_FINE_SEARCH_ARGS = { | |||
["Int Limit"] = 50, | |||
["Tenney Height"] = 1/0, | |||
["Complements Only"] = false | |||
} | |||
function p.preprocess_fine_search_args(fine_search_args) | |||
local fine_search_args = fine_search_args or DEFAULT_FINE_SEARCH_ARGS | |||
local tenney_height = fine_search_args["Tenney Height"] or 1/0 | |||
local comps_only = fine_search_args["Complements Only"] or false | |||
local int_limit = fine_search_args["Int Limit"] or DEFAULT_INT_LIMIT | |||
local | |||
local DEFAULT_INT_LIMIT = | return { | ||
["Tenney Height"] = tenney_height, | |||
["Complements Only"] = comps_only, | |||
["Int Limit"] = int_limit | |||
} | |||
end | |||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
| Line 48: | Line 54: | ||
-- Int limit is hardcoded to a max size to restrict the size of output, to avoid | -- Int limit is hardcoded to a max size to restrict the size of output, to avoid | ||
-- risk of out-of-memory operations or the like. | -- risk of out-of-memory operations or the like. | ||
function p.search_within_equave(equave, | function p.search_within_equave(equave, fine_search_args) | ||
local equave = equave or rat.new(2,1) -- Defualt equave is 2/1. | local equave = equave or rat.new(2,1) -- Defualt equave is 2/1. | ||
local | local fine_search_args = p.preprocess_fine_search_args(fine_search_args) | ||
local init_ratios = {{1,1}, {1,0}} | local init_ratios = {{1,1}, {1,0}} | ||
local search_func = p.int_limit_mediant_search | local search_func = p.int_limit_mediant_search | ||
local search_args = { [" | local search_args = { | ||
["Equave"] = equave, | |||
["Int Limit"] = fine_search_args["Int Limit"], | |||
["Tenney Height"] = fine_search_args["Tenney Height"] | |||
} | |||
local ratios = med.find_only_mediants_by_search_func(init_ratios, search_func, search_args) | local ratios = med.find_only_mediants_by_search_func(init_ratios, search_func, search_args) | ||
| Line 82: | Line 89: | ||
local mediant = mediant_data["mediant"] | local mediant = mediant_data["mediant"] | ||
local ratio_1 = mediant_data["ratio_1"] | local ratio_1 = mediant_data["ratio_1"] | ||
local equave = search_args[" | local equave = search_args["Equave"] | ||
local int_limit = search_args[" | local int_limit = search_args["Int Limit"] | ||
local tenney_height = search_args[" | local tenney_height = search_args["Tenney Height"] | ||
local equave_as_float = rat.as_float(equave) | local equave_as_float = rat.as_float(equave) | ||
| Line 105: | Line 112: | ||
-- Note that members in a subgroup need not be prime, as long as the terms are, | -- Note that members in a subgroup need not be prime, as long as the terms are, | ||
-- for the most part, relatively prime. | -- for the most part, relatively prime. | ||
function p.search_by_subgroup_within_equave(subgroup, equave, | function p.search_by_subgroup_within_equave(subgroup, equave, fine_search_args) | ||
local subgroup = subgroup or { 2, 3, 7 } | local subgroup = subgroup or { 2, 3, 7 } | ||
local equave = equave or rat.new(2,1) -- Defualt equave is 2/1. | local equave = equave or rat.new(2,1) -- Defualt equave is 2/1. | ||
local | local fine_search_args = p.preprocess_fine_search_args(fine_search_args) | ||
-- Be absolutely sure the subgroup's members are sorted! | -- Be absolutely sure the subgroup's members are sorted! | ||
table.sort(subgroup) | table.sort(subgroup) | ||
-- Fine search params for ease of access | |||
local int_limit = fine_search_args["Int Limit"] | |||
local tenney_height = fine_search_args["Tenney Height"] | |||
-- Find all possible products given the factors in the subgroup. | -- Find all possible products given the factors in the subgroup. | ||
| Line 192: | Line 202: | ||
-- Like subgroup search, prime limit search can also allow for very high int | -- Like subgroup search, prime limit search can also allow for very high int | ||
-- limits, as long as the prime is reasonably small. | -- limits, as long as the prime is reasonably small. | ||
function p.search_by_prime_limit_within_equave(prime_limit, equave, | function p.search_by_prime_limit_within_equave(prime_limit, equave, fine_search_args) | ||
local prime_limit = prime_limit or 5 | local prime_limit = prime_limit or 5 | ||
local equave = equave or rat.new(2,1) -- Defualt equave is 2/1. | local equave = equave or rat.new(2,1) -- Defualt equave is 2/1. | ||
local | local fine_search_args = p.preprocess_fine_search_args(fine_search_args) | ||
-- Find all primes up to the prime limit. | -- Find all primes up to the prime limit. | ||
| Line 215: | Line 224: | ||
-- Perform subgroup search on the primes found, as subgroup-search code can | -- Perform subgroup search on the primes found, as subgroup-search code can | ||
-- be reused for prime-limit search. | -- be reused for prime-limit search. | ||
return p.search_by_subgroup_within_equave(primes, equave, | return p.search_by_subgroup_within_equave(primes, equave, fine_search_args) | ||
end | end | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
------------------------- | -------------------------- ARG-BASED SEARCH FUNCTIONS -------------------------- | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
-- Search for ratios based on | -- Search for ratios based on an array of args passed in. Certain params have | ||
-- function calls. | -- their own function calls. | ||
function p. | function p.search_by_args_within_equave(equave, search_args) | ||
local equave = equave or rat.new(2,1) | local equave = equave or rat.new(2,1) | ||
-- | -- For each search method, check whether the corresponding search arg and | ||
-- | -- int limit are both present and pass it and the equave to that function. | ||
-- All other search args are used as finer search args. | |||
-- Note that search by int limit alone just has the equave and search args | |||
-- passed in. | |||
local ratios = {} | local ratios = {} | ||
if | if search_args["Prime Limit"] ~= nil and search_args["Int Limit"] ~= nil then | ||
ratios = p.search_by_prime_limit_within_equave( | ratios = p.search_by_prime_limit_within_equave(search_args["Prime Limit"], equave, search_args) | ||
elseif | elseif search_args["Subgroup"] ~= nil and search_args["Int Limit"] ~= nil then | ||
ratios = p.search_by_subgroup_within_equave( | ratios = p.search_by_subgroup_within_equave(search_args["Subgroup"], equave, search_args) | ||
elseif | elseif search_args["Int Limit"] ~= nil then | ||
ratios = p.search_within_equave(equave, | ratios = p.search_within_equave(equave, search_args) | ||
end | end | ||
return ratios | return ratios | ||
end | end | ||
-- Parse search | -- Parse search args. | ||
function p. | function p.parse_search_args(search_args) | ||
local parsed = tip.parse_kv_pairs( | local parsed = tip.parse_kv_pairs(search_args) | ||
if parsed["Int Limit"] ~= nil then | if parsed["Int Limit"] ~= nil then | ||
| Line 258: | Line 270: | ||
if parsed["Subgroup"] ~= nil then | if parsed["Subgroup"] ~= nil then | ||
parsed["Subgroup"] = tip.parse_numeric_entries(parsed["Subgroup"], ".") | parsed["Subgroup"] = tip.parse_numeric_entries(parsed["Subgroup"], ".") | ||
end | |||
if parsed["Complements Only"] ~= nil then | |||
parsed["Complements Only"] = yesno(parsed["Complements Only"]) | |||
end | end | ||
| Line 263: | Line 279: | ||
end | end | ||
function p. | function p.search_footnotes(search_args) | ||
local result = "Other interpretations are possible." | local result = "Other interpretations are possible." | ||
local autosearch_text = "Automatic search may include irrelevant ratios and may not include all notable ratios." | local autosearch_text = "Automatic search may include irrelevant ratios and may not include all notable ratios." | ||
local search_text = "" | local search_text = "" | ||
if | if search_args["Prime Limit"] ~= nil then | ||
search_text = string.format("Ratios shown are within the %s-prime limit.", | search_text = string.format("Ratios shown are within the %s-prime limit.", search_args["Prime Limit"]) | ||
.. " " .. autosearch_text | .. " " .. autosearch_text | ||
elseif | elseif search_args["Subgroup"] ~= nil then | ||
search_text = string.format("Ratios shown are within the %s subgroup.", table.concat( | search_text = string.format("Ratios shown are within the %s subgroup.", table.concat(search_args["Subgroup"], ".")) | ||
.. " " .. autosearch_text | .. " " .. autosearch_text | ||
elseif | elseif search_args["Int Limit"] ~= nil then | ||
search_text = string.format("Ratios shown are within the %s-integer limit.", | search_text = string.format("Ratios shown are within the %s-integer limit.", search_args["Int Limit"]) | ||
.. " " .. autosearch_text | .. " " .. autosearch_text | ||
end | end | ||
| Line 368: | Line 384: | ||
--return p.ratios_as_text(ratios) | --return p.ratios_as_text(ratios) | ||
local fine_search_args = {["Complements Only"] = true, ["Int Limit"] = 40, ["Subgroup"] = {2,3,7}} | |||
return p. | return p.ratios_as_text(p.search_by_args_within_equave(rat.new(3,2), fine_search_args)) | ||
end | end | ||
return p | return p | ||