Module:JI ratios: Difference between revisions

Ganaram inukshuk (talk | contribs)
m todo
Ganaram inukshuk (talk | contribs)
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.


-- INT_LIMIT_MAX is hardcoded to limit the size of output. This only applies to
local DEFAULT_FINE_SEARCH_ARGS = {
-- int limit search, as other search functions (subgroup, prime-limit) may allow
["Int Limit"]        = 50,
-- higher search maxima. For reference, searching within the octave yields this
["Tenney Height"]    = 1/0,
-- many ratios:
["Complements Only"] = false
-- 400 -> ~24000 ratios
}
-- 300 -> ~14000 ratios
 
-- 250 -> ~9500 ratios
function p.preprocess_fine_search_args(fine_search_args)
-- 200 -> ~6000 ratios
local fine_search_args = fine_search_args or DEFAULT_FINE_SEARCH_ARGS
-- 150 -> ~3400 ratios
local tenney_height = fine_search_args["Tenney Height"] or 1/0
-- 128 -> ~2500 ratios
local comps_only    = fine_search_args["Complements Only"] or false
-- 100 -> ~1500 ratios
local int_limit    = fine_search_args["Int Limit"] or DEFAULT_INT_LIMIT
local INT_LIMIT_MAX = 200
local DEFAULT_INT_LIMIT = 50
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, int_limit, tenney_height)
function p.search_within_equave(equave, fine_search_args)
local int_limit = int_limit or DEFAULT_INT_LIMIT
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 tenney_height = tenney_height or 1/0 -- Defualt tenney height is infinity.
local fine_search_args = p.preprocess_fine_search_args(fine_search_args)
int_limit = math.max(1, math.min(INT_LIMIT_MAX, int_limit))
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 = { ["equave"] = equave, ["int_limit"] = int_limit, ["tenney_height"] = tenney_height }
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["equave"]
local equave        = search_args["Equave"]
local int_limit    = search_args["int_limit"]
local int_limit    = search_args["Int Limit"]
local tenney_height = search_args["tenney_height"]
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, int_limit, tenney_height)
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 int_limit = int_limit or 50
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 tenney_height = tenney_height or 1/0 -- Defualt tenney height is infinity.
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, int_limit, tenney_height)
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 int_limit = int_limit or 1000
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 tenney_height = tenney_height or 1/0 -- Defualt tenney height is infinity.
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, int_limit, tenney_height)
return p.search_by_subgroup_within_equave(primes, equave, fine_search_args)
end
end


--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
------------------------- PARAM-BASED SEARCH FUNCTIONS -------------------------
-------------------------- ARG-BASED SEARCH FUNCTIONS --------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------


-- Search for ratios based on params passed in. Certain params have their own
-- Search for ratios based on an array of args passed in. Certain params have
-- function calls.
-- their own function calls.
function p.search_by_params(params, equave)
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)
-- First get ratios up to an int limit. If no int limit was passed in, it
-- For each search method, check whether the corresponding search arg and
-- will default to the hardcoded default value.
-- 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 params["Prime Limit"] ~= nil and params["Int Limit"] ~= nil then
if search_args["Prime Limit"] ~= nil and search_args["Int Limit"] ~= nil then
ratios = p.search_by_prime_limit_within_equave(params["Prime Limit"], equave, params["Int Limit"], params["Tenney Height"])
ratios = p.search_by_prime_limit_within_equave(search_args["Prime Limit"], equave, search_args)
elseif params["Subgroup"] ~= nil and params["Int Limit"] ~= nil then
elseif search_args["Subgroup"] ~= nil and search_args["Int Limit"] ~= nil then
ratios = p.search_by_subgroup_within_equave(params["Subgroup"], equave, params["Int Limit"], params["Tenney Height"])
ratios = p.search_by_subgroup_within_equave(search_args["Subgroup"], equave, search_args)
elseif params["Int Limit"] ~= nil then
elseif search_args["Int Limit"] ~= nil then
ratios = p.search_within_equave(equave, params["Int Limit"], params["Tenney Height"])
ratios = p.search_within_equave(equave, search_args)
end
end
return ratios
return ratios
end
end


-- Parse search params.
-- Parse search args.
function p.parse_search_params(search_params)
function p.parse_search_args(search_args)
local parsed = tip.parse_kv_pairs(search_params)
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.search_param_footnotes(search_params)
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 search_params["Prime Limit"] ~= nil then
if search_args["Prime Limit"] ~= nil then
search_text = string.format("Ratios shown are within the %s-prime limit.", search_params["Prime Limit"])
search_text = string.format("Ratios shown are within the %s-prime limit.", search_args["Prime Limit"])
.. " " .. autosearch_text
.. " " .. autosearch_text
elseif search_params["Subgroup"] ~= nil then
elseif search_args["Subgroup"] ~= nil then
search_text = string.format("Ratios shown are within the %s subgroup.", table.concat(search_params["Subgroup"], "."))
search_text = string.format("Ratios shown are within the %s subgroup.", table.concat(search_args["Subgroup"], "."))
.. " " .. autosearch_text
.. " " .. autosearch_text
elseif search_params["Int Limit"] ~= nil then
elseif search_args["Int Limit"] ~= nil then
search_text = string.format("Ratios shown are within the %s-integer limit.", search_params["Int 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.parse_search_params("Prime Limit: 19")
return p.ratios_as_text(p.search_by_args_within_equave(rat.new(3,2), fine_search_args))
end
end


return p
return p