Module:JI ratio finder: Difference between revisions
m find_ratio_for_cents now returns ratios (as lua tables), not text |
Added function to find candidate ratios, intended for finding multiple sets of ratios; added filter functions |
||
| Line 4: | Line 4: | ||
local p = {} | local p = {} | ||
-- | -- 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 | ||