Module:JI ratio finder: Difference between revisions

Ganaram inukshuk (talk | contribs)
Removed exact-ratio filtering (ji-ratios-in-ed doesn't need it anymore)
Ganaram inukshuk (talk | contribs)
Added subgroup search and filtering
Line 22: Line 22:
local equave = equave or rat.new(2)
local equave = equave or rat.new(2)
return rat.mul(rat.inv(ratio), equave)
return rat.mul(rat.inv(ratio), equave)
end
-- Determines whether a ratios is within a subgroup; for a subgroup p1.p2..pn,
-- a ratio p/q is in that subgroup if its prime factorization contains any prime
-- factors p1, p2, .. pn.
function p.within_subgroup(ratio, subgroup)
local ratio = ratio or rat.new(5, 2)
local subgroup = subgroup or { 2, 3, 5 }
local within_subgroup = ""
for key, value in pairs(ratio) do
if key ~= "sign" then
within_subgroup = within_subgroup and utils.table_contains(subgroup, key)
end
end
return within_subgroup
end
end


Line 47: Line 64:
if is_simplified and is_within_cents and is_within_prime_limit then
if is_simplified and is_within_cents and is_within_prime_limit then
table.insert(candidate_ratios, current_ratio)
end
numerator = numerator + 1
until not is_within_cents
end
return candidate_ratios
end
-- Finds candidate ratios up to a cent value, up to a denominator limit, and
-- within a prime subgroup.
-- These ratios should be filtered as needed.
function p.find_candidate_ratios_within_subgroup(cents, denominator_limit, subgroup)
local cents = cents or 1200
local denominator_limit = denominator_limit or 99
local subgroup = subgroup or { 2, 3, 7, 11 }
local candidate_ratios = {}
for i = 1, denominator_limit do
local denominator = i
local numerator = i
local is_within_cents = true
repeat
local current_ratio = rat.new(numerator, denominator)
local is_simplified = utils._gcd(numerator, denominator) == 1
local is_within_subgroup = p.within_subgroup(current_ratio, subgroup)
is_within_cents = rat.cents(current_ratio) <= cents
if is_simplified and is_within_cents and is_within_subgroup then
table.insert(candidate_ratios, current_ratio)
table.insert(candidate_ratios, current_ratio)
end
end
Line 120: Line 170:
if rat.max_prime(ratios[i]) == harmonic_class then
if rat.max_prime(ratios[i]) == harmonic_class then
table.insert(filtered_ratios, ratios[i])
table.insert(filtered_ratios, ratios[i])
end
end
return filtered_ratios
end
-- Filters ratios by prime subgroup (such as 2.3.5)
-- Filters out ratios whose factors are not in the given subgroup; this requires
-- filtering by each prime as a harmonic class
function p.filter_ratios_by_subgroup(ratios, subgroup)
local ratios = ratios or { rat.new(1), rat.new(5, 4), rat.new(81, 64), rat.new(9, 7) }
local subgroup = subgroup or { 2, 3, 5 }
local candidate_ratios = p.filter_ratios_by_prime_limit(ratios, subgroup[#subgroup])
local filtered_ratios = {}
for i = 1, #subgroup do
local prime_filtered_ratios = p.filter_ratios_by_harmonic_class(candidate_ratios, subgroup[i])
for j = 1, #prime_filtered_ratios do
table.insert(filtered_ratios, prime_filtered_ratios[j])
end
end
end
end