Module:JI ratio finder: Difference between revisions

From Xenharmonic Wiki
Jump to navigation Jump to search
Ganaram inukshuk (talk | contribs)
m Comments; logic adjusted for finding the unison
Ganaram inukshuk (talk | contribs)
Removed odd-limit function, as it's now part of Module:Rational
Line 3: Line 3:
local rat = require('Module:Rational')
local rat = require('Module:Rational')
local p = {}
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
-- Main function
Line 53: Line 38:
within_min_tolerance = ratio_in_cents > cents - tolerance
within_min_tolerance = ratio_in_cents > cents - tolerance
within_max_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_odd_limit = rat.odd_limit(current_ratio) <= odd_limit
within_prime_limit = rat.max_prime(current_ratio) <= prime_limit
within_prime_limit = rat.max_prime(current_ratio) <= prime_limit
is_simplified = utils._gcd(num, den) == 1
is_simplified = utils._gcd(num, den) == 1

Revision as of 06:03, 11 January 2024

Module documentation[view] [edit] [history] [purge]

Todo: add documentation


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



return p