Module:JI ratio finder: Difference between revisions
Added function to find candidate ratios, intended for finding multiple sets of ratios; added filter functions |
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 | ||