Module:JI ratio finder: Difference between revisions
Jump to navigation
Jump to search
Created lua translation of JIRAF; work-in-progress, as some limitations need tweaking |
m Comments; logic adjusted for finding the unison |
||
Line 21: | Line 21: | ||
-- Main function | -- Main function | ||
-- 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 | ||
function p. | function p.find_ratios_for_cents(cents, tolerance, prime_limit, odd_limit) | ||
local cents = cents or | local cents = cents or 700 | ||
local tolerance = tolerance or | local tolerance = tolerance or 20 | ||
local prime_limit = prime_limit or | local prime_limit = prime_limit or 5 | ||
local odd_limit = odd_limit or | local odd_limit = odd_limit or 49 | ||
local num = 1 | local num = 1 | ||
Line 38: | Line 38: | ||
local found_ratios = {} | 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 | ||
repeat | repeat | ||
local current_ratio = rat.new(num, den) | local current_ratio = rat.new(num, den) | ||
local ratio_in_cents = rat.cents(current_ratio) | local ratio_in_cents = rat.cents(current_ratio) | ||
Line 55: | Line 60: | ||
table.insert(found_ratios, rat.as_ratio(current_ratio)) | table.insert(found_ratios, rat.as_ratio(current_ratio)) | ||
end | end | ||
-- Increment numerator | |||
num = num + 1 | |||
until not within_max_tolerance | until not within_max_tolerance |
Revision as of 02:55, 11 January 2024
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.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 = 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
-- Increment numerator
num = num + 1
until not within_max_tolerance
den = den + 1
num = den
until not within_odd_limit
return found_ratios
end
return p