Module:JI ratios: Difference between revisions

Ganaram inukshuk (talk | contribs)
mNo edit summary
Ganaram inukshuk (talk | contribs)
comment out filter functions, to be merged into one filter function; remove redundant/unneeded functions/calls
Line 27: Line 27:
-- - Tenney height is used for further filtering of ratios, and is considered
-- - Tenney height is used for further filtering of ratios, and is considered
--  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
}


--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Line 38: Line 32:
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------


-- Filter functions remove certain ratios that don't meet some requirement.
-- Filter function removes certain ratios that don't meet some requirement.
-- Filters currently include:
-- Filters currently include:
-- - Removing ratios that exceed a max Tenney height.
-- - Removing ratios that exceed a max Tenney height.
-- - Removing ratios whose complement would exceed a max Tenney height.
-- - Removing ratios whose complement would exceed a max Tenney height.
-- TODO: combine into one filter function
--[[


-- Remove ratios whose complements exceed the int limit and Tenney height.
-- Remove ratios whose complements exceed the int limit and Tenney height.
Line 72: Line 70:
return filtered_ratios
return filtered_ratios
end
end
]]--


--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Line 77: Line 77:
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------


-- Int-limit-based search; finds ratios between 1/1 and an equave, within an int
-- Int limit search finds ratios from 1/1 to an equave
-- limit.
function p.search_by_int_limit(equave, int_limit)
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 int_limit = int_limit or 50 -- Default is 50
--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 ratios = med.find_only_mediants_by_int_limit(init_ratios, fine_search_args["Int Limit"])
local ratios = med.find_only_mediants_by_int_limit(init_ratios, int_limit)
-- Convert to ratios that Module:Rational can work with
-- Convert to ratios that Module:Rational can work with
Line 100: Line 99:
-- Filter out ratios that exceed the int limit.
-- Filter out ratios that exceed the int limit.
-- Then filter out ratios if their equave complement would be filtered out.
-- Then filter out ratios if their equave complement would be filtered out.
ratios = p.filter_ratios_by_tenney_height(ratios, equave, fine_search_args)
--ratios = p.filter_ratios_by_tenney_height(ratios, equave, fine_search_args)
ratios = p.filter_ratios_by_complements(ratios, equave, fine_search_args)
--ratios = p.filter_ratios_by_complements(ratios, equave, fine_search_args)
return ratios
return ratios
Line 116: Line 115:
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------


function p.search_by_prime_limit(prime_limit, equave, fine_search_args)
function p.search_by_prime_limit(equave, int_limit, prime_limit)
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)
local int_limit  = int_limit or 50 -- Default is 50
--local fine_search_args = p.preprocess_fine_search_args(fine_search_args)
local prime_limit = prime_limit or 5 -- Default is 5-prime-limit


-- Find all primes up to the prime limit.
-- Convert prime limit into an equivalent subgroup (EG, 7-limit becomes
-- 2.3.5.7) so that it can be passed into the subgroup search function.
local primes = {}
local primes = {}
for i = 2, prime_limit do
for i = 2, prime_limit do
Line 136: Line 136:
end
end
-- Perform subgroup search on the primes found, as subgroup-search code can
return p.search_by_subgroup(equave, int_limit, primes)
-- be reused for prime-limit search.
return p.search_by_subgroup(primes, equave, fine_search_args)
end
end


Line 145: Line 143:
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------


function p.search_by_subgroup(subgroup, equave, fine_search_args)
function p.search_by_subgroup(equave, int_limit, subgroup)
local subgroup = subgroup or {rat.new(2), rat.new(3), rat.new(7)}
local equave    = equave or rat.new(2,1) -- Defualt equave is 2/1.
local equave = equave or rat.new(2,1)
local int_limit = int_limit or 50 -- Default is 50
--local fine_search_args = p.preprocess_fine_search_args(fine_search_args)
local subgroup = subgroup or {rat.new(2), rat.new(3), rat.new(7)} -- Default is 2.3.7 subgroup
-- Fine search params for ease of access
local tenney_height = fine_search_args["Tenney Height"]
local comps_only = fine_search_args["Complements Only"]
local int_limit = fine_search_args["Int Limit"]
-- Search for ratios within int limit within subgroup by multiplication.
-- Search for ratios within int limit within subgroup by multiplication.
Line 181: Line 174:
-- Then filter out ratios if their equave complement would be filtered out.
-- Then filter out ratios if their equave complement would be filtered out.
table.sort(ratios, rat.lt)
table.sort(ratios, rat.lt)
ratios = p.filter_ratios_by_tenney_height(ratios, equave, fine_search_args)
ratios = p.filter_ratios_by_complements(ratios, equave, fine_search_args)
return ratios
return ratios
Line 231: Line 222:
end
end
return found
return found
end
--------------------------------------------------------------------------------
-------------------------- ARG-BASED SEARCH FUNCTIONS --------------------------
--------------------------------------------------------------------------------
-- Search for ratios based on an array of args passed in. Certain params have
-- their own function calls.
function p.search_by_args_within_equave(equave, search_args)
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 = {}
if search_args["Prime Limit"] ~= nil and search_args["Int Limit"] ~= nil then
ratios = p.search_by_prime_limit(search_args["Prime Limit"], equave, search_args)
elseif search_args["Subgroup"] ~= nil and search_args["Int Limit"] ~= nil then
ratios = p.search_by_subgroup(search_args["Subgroup"], equave, search_args)
elseif search_args["Int Limit"] ~= nil then
ratios = p.search_within_equave(equave, search_args)
end
return ratios
end
-- Parse search args.
function p.parse_search_args(search_args)
local parsed = tip.parse_kv_pairs(search_args)
if parsed["Int Limit"] ~= nil then
parsed["Int Limit"] = tonumber(parsed["Int Limit"])
end
if parsed["Tenney Height"] ~= nil then
parsed["Tenney Height"] = tonumber(parsed["Tenney Height"])
end
if parsed["Prime Limit"] ~= nil then
parsed["Prime Limit"] = tonumber(parsed["Prime Limit"])
end
if parsed["Subgroup"] ~= nil then
local subgroup_elements = tip.parse_numeric_pairs(parsed["Subgroup"], ".", "/", true)
for i = 1, #subgroup_elements do
subgroup_elements[i] = rat.new(subgroup_elements[i][1], subgroup_elements[i][2])
end
parsed["Subgroup"] = subgroup_elements
end
if parsed["Complements Only"] ~= nil then
parsed["Complements Only"] = yesno(parsed["Complements Only"])
end
return parsed
end
end


Line 326: Line 261:


-- Function callable by other modules
-- Function callable by other modules
-- Search hierarchy is as follows:
-- - Search by subgroup (includes non-integer and rational elements)
-- - Then search by prime limit
-- - Then search by odd limit (to be implemented)
-- - Then search by int limit
function p._ji_ratios(args)
function p._ji_ratios(args)
-- Args for ease of access
equave      = args["Equave"]
int_limit  = args["Int Limit"]
odd_limit  = args["Odd Limit"]
prime_limit = args["Prime Limit"]
subgroup    = args["Subgroup"]
local ratios = {}
if search_args["Subgroup"] ~= nil then
ratios = p.search_by_subgroup(equave, int_limit, subgroup)
elseif search_args["Prime Limit"] ~= nil then
ratios = p.search_by_prime_limit(equave, int_limit, prime_limit)
elseif search_args["Int Limit"] ~= nil then
ratios = p.search_by_int_limit(equave, int_limit)
end
return ratios
end
end


-- Invokable function; for templates
-- Invokable function; for templates
-- Ratios are returned as a comma-delimited list
function p.ji_ratios(frame)
function p.ji_ratios(frame)
args = getArgs(frame)
args = getArgs(frame)
args["Equave"] = rat.parse(args["Equave"])
-- Preprocess equave
-- Ratios are searched from 1/1 to some equave (default 2/1), so an equave
-- must be passed in.
args["Equave"] = args["Equave"] ~= nil and rat.parse(args["Equave"]) or rat.new(2,1)
-- Preprocess int limit
-- Ratios are searched up to some int limit (default 50), so an int limit
-- must be passed in.
args["Int Limit"] = args["Int Limit"] ~= nil and tonumber(args["Int Limit"]) or 50


 
-- Preprocess Tenney height
if args["Int Limit"] ~= nil then
args["Int Limit"] = tonumber(args["Int Limit"])
end
if args["Tenney Height"] ~= nil then
if args["Tenney Height"] ~= nil then
args["Tenney Height"] = tonumber(args["Tenney Height"]) or math.huge
args["Tenney Height"] = tonumber(args["Tenney Height"])
end
end
-- Preprocess prime limit
if args["Prime Limit"] ~= nil then
if args["Prime Limit"] ~= nil then
args["Prime Limit"] = tonumber(args["Prime Limit"])
args["Prime Limit"] = tonumber(args["Prime Limit"])
end
end
-- Preprocess subgroup
if args["Subgroup"] ~= nil then
if args["Subgroup"] ~= nil then
local subgroup_elements = tip.parse_numeric_pairs(args["Subgroup"], ".", "/", true)
local subgroup_elements = tip.parse_numeric_pairs(args["Subgroup"], ".", "/", true)
Line 361: Line 324:
end
end
-- Find and return ratios
ratios = p.search_by_args_within_equave(args["Equave"], args)
ratios = p._ji_ratios(args)
return p.ratios_as_string(ratios)
return p.ratios_as_string(ratios)
end
end