Module:JI ratio finder: Difference between revisions
Jump to navigation
Jump to search
Removed odd-limit function, as it's now part of Module:Rational |
Added ratios-to-text |
||
Line 59: | Line 59: | ||
end | end | ||
function p.ratios_to_text(ratios) | |||
local ratios = ratios or { rat.new(5, 4), rat.new (81, 64) } | |||
local text = "" | |||
for i = 1, #ratios do | |||
text = text .. rat.as_ratio(ratios[i]) | |||
if i ~= #ratios then | |||
text = text .. ", " | |||
end | |||
end | |||
return text | |||
end | |||
return p | return p |
Revision as of 08:16, 11 January 2024
local utils = require('Module:Utils')
local interval = require('Module:Interval')
local rat = require('Module:Rational')
local p = {}
-- Main function
-- Finds approximated JI ratios for a cent value for a prime and odd limit
function p.find_ratios_for_cents(cents, tolerance, prime_limit, odd_limit)
local cents = cents or 700
local tolerance = tolerance or 20
local prime_limit = prime_limit or 5
local odd_limit = odd_limit or 49
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 = {}
-- Algorithm is as follows:
-- Start with a unison p/q, where p=q and check whether it's within the
-- range of the target ratio. If so, record it. Increment p by 1 and repeat
-- until p/q exceeds the target range.
-- Once p/q exceeds the range of the target ratio, increment q and repeat
-- the process described above. End this process once p or q exceed a
-- specified limit (the odd limit, in this case).
repeat
repeat
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 = rat.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
-- Increment numerator
num = num + 1
until not within_max_tolerance
den = den + 1
num = den
until not within_odd_limit
return found_ratios
end
function p.ratios_to_text(ratios)
local ratios = ratios or { rat.new(5, 4), rat.new (81, 64) }
local text = ""
for i = 1, #ratios do
text = text .. rat.as_ratio(ratios[i])
if i ~= #ratios then
text = text .. ", "
end
end
return text
end
return p