Module:JI ratio finder: Difference between revisions

Ganaram inukshuk (talk | contribs)
Added function to find candidate ratios, intended for finding multiple sets of ratios; added filter functions
Ganaram inukshuk (talk | contribs)
Added filtering by complement-agnostic Tenney height (eg, 4/3 and 3/2 will report the same Tenney height, defined as which height between the two is smaller)
Line 3: Line 3:
local rat = require('Module:Rational')
local rat = require('Module:Rational')
local p = {}
local p = {}
-- Finds the Tenney height of a ratio, regardless of inversion; also called
-- complement-agnostic tenney height (CATH). Equave complement depends on what
-- the equivalence interval is (default is 2/1).
-- Given a ratio and its equave complement, the CATH is the smaller of the two
-- ratios' Tenney heights.
function p.complement_agnostic_tenney_height(ratio, equave)
local ratio = ratio or rat.new(81, 64)
local equave = equave or rat.new(2)
local comp = p.equave_complement(ratio, equave)
return math.min(rat.tenney_height(ratio), rat.tenney_height(comp))
end
-- Finds the equave complement of a ratio.
-- For a ratio a/b and equave p/q, the equave complement of a/b is c/d, such
-- that multiplying a/b and c/d equals p/q. In other words, c/d is p/q * b/a.
function p.equave_complement(ratio, equave)
local equave = equave or rat.new(2)
return rat.mul(rat.inv(ratio), equave)
end


-- Finds candidate ratios up to a cent value and up to an integer limit
-- Finds candidate ratios up to a cent value and up to an integer limit
Line 113: Line 133:
for i = 1, #ratios do
for i = 1, #ratios do
if rat.tenney_height(ratios[i]) <= tenney_height then
if rat.tenney_height(ratios[i]) <= tenney_height then
table.insert(filtered_ratios, ratios[i])
end
end
return filtered_ratios
end
-- Filters ratios by complement-agnostic Tenney height
-- Filters ratios where lg(numerator) + lg(denominator) does not exceed the
-- given height, where lg is log-base-2
-- If the equave complement of that ratio has a lower Tenney height, the ratio
-- is kept instead.
function p.filter_ratios_by_complement_agnostic_tenney_height(ratios, tenney_height, equave)
local ratios = ratios or { rat.new(5, 4), rat.new(81, 64), rat.new(9, 7) }
local tenney_height = tenney_height or 5.0
local equave = equave or rat.new(2)
local filtered_ratios = {}
for i = 1, #ratios do
if p.complement_agnostic_tenney_height(ratios[i], equave) <= tenney_height then
table.insert(filtered_ratios, ratios[i])
table.insert(filtered_ratios, ratios[i])
end
end