local utils = require('Module:Utils')
local interval = require('Module:Interval')
local rat = require('Module:Rational')
local p = {}
-- Helper function
-- Finds the odd limit of a ratio
-- why isnt this in rat
function p.odd_limit(a)
local a_copy = rat.copy(a)
if a_copy[2] ~= nil then
a_copy[2] = 0
end
local num, den = rat.as_pair(a_copy)
return math.max(num, den)
end
-- Main function
-- Finds approximated JI ratios for a cent value for a prime and odd limit
function p.cents_to_approx_ratios(cents, tolerance, prime_limit, odd_limit)
local cents = cents or 0
local tolerance = tolerance or 25
local prime_limit = prime_limit or 19
local odd_limit = odd_limit or 19
local num = 1
local den = 1
local within_min_tolerance = true
local within_max_tolerance = true
local within_odd_limit = true
local within_prime_limit = true
local is_simplified = true
local found_ratios = {}
repeat
repeat
num = num + 1
local current_ratio = rat.new(num, den)
local ratio_in_cents = rat.cents(current_ratio)
-- Check conditions
within_min_tolerance = ratio_in_cents > cents - tolerance
within_max_tolerance = ratio_in_cents < cents + tolerance
within_odd_limit = p.odd_limit(current_ratio) <= odd_limit
within_prime_limit = rat.max_prime(current_ratio) <= prime_limit
is_simplified = utils._gcd(num, den) == 1
if within_min_tolerance and is_simplified and within_prime_limit and within_max_tolerance and within_odd_limit then
table.insert(found_ratios, rat.as_ratio(current_ratio))
end
until not within_max_tolerance
den = den + 1
num = den
until not within_odd_limit
return found_ratios
end
return p