Module:JI ratio finder: Difference between revisions

Ganaram inukshuk (talk | contribs)
m find_ratio_for_cents now returns ratios (as lua tables), not text
Ganaram inukshuk (talk | contribs)
Added function to find candidate ratios, intended for finding multiple sets of ratios; added filter functions
Line 4: Line 4:
local p = {}
local p = {}


-- Main function
-- Finds candidate ratios up to a cent value and up to an integer limit
-- Ratios found this way will range from 0 cents to the given cent value
-- These ratios should then be filtered as needed
function p.find_candidate_ratios(cents, int_limit)
local cents = cents or 1200
local int_limit = int_limit or 99
local candidate_ratios = {}
for i = 1, int_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
is_within_cents = rat.cents(current_ratio) <= cents
if is_simplified and is_within_cents then
table.insert(candidate_ratios, current_ratio)
end
numerator = numerator + 1
until not is_within_cents
end
return candidate_ratios
end
 
-- Filter ratios based on whether they're within a cent range
function p.filter_ratios_by_range(ratios, min_cents, max_cents)
local ratios = ratios or { rat.new(5, 4), rat.new(81, 64), rat.new(9, 7) }
local min_cents = min_cents or 380
local max_cents = max_cents or 420
local filtered_ratios = {}
for i = 1, #ratios do
local ratio_in_cents = rat.cents(ratios[i])
if ratio_in_cents >= min_cents and ratio_in_cents <= max_cents then
table.insert(filtered_ratios, ratios[i])
end
end
return filtered_ratios
end
 
-- Filters ratios by prime limit
-- Filters out ratios whose prime factorizations contains primes larger than
-- the prime limit
function p.filter_ratios_by_prime_limit(ratios, prime_limit)
local ratios = ratios or { rat.new(5, 4), rat.new(81, 64), rat.new(9, 7) }
local prime_limit = prime_limit or 5
local filtered_ratios = {}
for i = 1, #ratios do
if rat.max_prime(ratios[i]) <= prime_limit then
table.insert(filtered_ratios, ratios[i])
end
end
return filtered_ratios
end
 
-- Filters ratios by odd limit
-- Filters out ratios where, ignoring powers of 2, either the numerator or
-- denominator exceeds the odd limit
function p.filter_ratios_by_odd_limit(ratios, odd_limit)
local ratios = ratios or { rat.new(5, 4), rat.new(81, 64), rat.new(9, 7) }
local odd_limit = odd_limit or 5
local filtered_ratios = {}
for i = 1, #ratios do
if rat.odd_limit(ratios[i]) <= odd_limit then
table.insert(filtered_ratios, ratios[i])
end
end
return filtered_ratios
end
 
-- Filters ratios by harmonic class
-- Filters out ratios whose largest prime is larger than the given prime; only
-- ratios whose largest prime is the given harmonic class are kept
function p.filter_ratios_by_harmonic_class(ratios, harmonic_class)
local ratios = ratios or { rat.new(5, 4), rat.new(81, 64), rat.new(9, 7) }
local harmonic_class = harmonic_class or 5
local filtered_ratios = {}
for i = 1, #ratios do
if rat.max_prime(ratios[i]) == harmonic_class then
table.insert(filtered_ratios, ratios[i])
end
end
return filtered_ratios
end
 
-- Filters ratios by Tenney height
-- Filters ratios where lg(numerator) + lg(denominator) does not exceed the
-- given height, where lg is log-base-2
function p.filter_ratios_by_tenney_height(ratios, tenney_height)
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 filtered_ratios = {}
for i = 1, #ratios do
if rat.tenney_height(ratios[i]) <= tenney_height then
table.insert(filtered_ratios, ratios[i])
end
end
return filtered_ratios
end
 
-- Finds approximated JI ratios for a cent value for a prime and odd limit
-- Finds approximated JI ratios for a cent value for a prime and odd limit
-- Meant to find ratios within the range of a single cent value
-- TODO: use integer limit instead of odd limit
function p.find_ratios_for_cents(cents, tolerance, prime_limit, odd_limit)
function p.find_ratios_for_cents(cents, tolerance, prime_limit, odd_limit)
local cents = cents or 700
local cents = cents or 700
Line 59: Line 176:
end
end


function p.ratios_to_text(ratios)
-- Converts ratios to text, with delimiter
-- Default delimiter is a comma followed by a space
function p.ratios_to_text(ratios, delimiter)
local ratios = ratios or { rat.new(5, 4), rat.new (81, 64) }
local ratios = ratios or { rat.new(5, 4), rat.new (81, 64) }
local delimiter = delimiter or ", "


local text = ""
local text = ""
Line 66: Line 186:
text = text .. rat.as_ratio(ratios[i])
text = text .. rat.as_ratio(ratios[i])
if i ~= #ratios then
if i ~= #ratios then
text = text .. ", "
text = text .. delimiter
end
end
end
end
return text
return text
end
end


return p
return p