Module:Limits: Difference between revisions

Plumtree (talk | contribs)
mNo edit summary
Plumtree (talk | contribs)
m Refactoring
Line 1: Line 1:
local rat = require('Module:Rational')
local rat = require('Module:Rational')
local ET = require('Module:ET')
local p = {}
local p = {}


Line 41: Line 42:
-- `distinct`: whether distinct ratios are required to be mapped to distinct approximations
-- `distinct`: whether distinct ratios are required to be mapped to distinct approximations
-- `previous`: already computed ratios for the previous iteraton
-- `previous`: already computed ratios for the previous iteraton
function p.additively_consistent(equave, size, ratios, distinct, previous)
function p.additively_consistent(et, ratios, distinct, previous)
distinct = distinct or false
distinct = distinct or false
previous = previous or {}
previous = previous or {}
local function approximate(a)
return math.floor(size * math.log(rat.as_float(a)) / math.log(rat.as_float(equave)) + 0.5)
end
if distinct then
if distinct then
local approx_set = {}
local approx_set = {}
for a_key, a in pairs(previous) do
for a_key, a in pairs(previous) do
local a_approx = approximate(a) % size
local a_approx = ET.approximate(et, rat.as_float(a)) % et.size
if approx_set[a_approx] then
if approx_set[a_approx] then
return false
return false
Line 57: Line 55:
end
end
for a_key, a in pairs(ratios) do
for a_key, a in pairs(ratios) do
local a_approx = approximate(a) % size
local a_approx = ET.approximate(et, rat.as_float(a)) % et.size
if approx_set[a_approx] then
if approx_set[a_approx] then
return false
return false
Line 73: Line 71:
end
end
for i, a in ipairs(ratios_ordered) do
for i, a in ipairs(ratios_ordered) do
local a_approx = approximate(a)
local a_approx = ET.approximate(et, rat.as_float(a))
for j, b in ipairs(previous_ordered) do
for j, b in ipairs(previous_ordered) do
local b_approx = approximate(b)
local b_approx = ET.approximate(et, rat.as_float(b))
local c = rat.mul(a, b)
local c = rat.mul(a, b)
local c_approx = approximate(c)
local c_approx = ET.approximate(et, rat.as_float(c))
c = rat.modulo_mul(c, equave)
c = rat.modulo_mul(c, et.equave)
local c_key = rat.as_ratio(c)
local c_key = rat.as_ratio(c)
if previous[c_key] or ratios[c_key] then
if previous[c_key] or ratios[c_key] then
Line 92: Line 90:
for j, b in ipairs(ratios_ordered) do
for j, b in ipairs(ratios_ordered) do
if i <= j then
if i <= j then
local b_approx = approximate(b)
local b_approx = ET.approximate(et, rat.as_float(b))
local c = rat.mul(a, b)
local c = rat.mul(a, b)
local c_approx = approximate(c)
local c_approx = ET.approximate(et, rat.as_float(c))
c = rat.modulo_mul(c, equave)
c = rat.modulo_mul(c, et.equave)
local c_key = rat.as_ratio(c)
local c_key = rat.as_ratio(c)
if previous[c_key] or ratios[c_key] then
if previous[c_key] or ratios[c_key] then
Line 115: Line 113:
-- returns nil when at least `max_n`
-- returns nil when at least `max_n`
-- `distinct`: whether distinct ratios are required to be mapped to distinct approximations
-- `distinct`: whether distinct ratios are required to be mapped to distinct approximations
function p.consistency_limit(size, equave, distinct, max_n)
function p.consistency_limit(et, distinct, max_n)
if size == 0 then
if et.size == 0 then
-- the answer is known already
-- the answer is known already
return '∞'
return '∞'
end
end
max_n = max_n or 1/0
max_n = max_n or 1/0
equave = equave or 2
distinct = distinct or false
distinct = distinct or false
local n = 1
local n = 1
Line 127: Line 124:
local previous = {}
local previous = {}
while true do
while true do
local ratios = p.limit_modulo_equave(n, equave, previous)
local ratios = p.limit_modulo_equave(n, et.equave, previous)
for key, ratio in pairs(ratios) do
for key, ratio in pairs(ratios) do
mw.log('step ' .. n .. ': ' .. key)
mw.log('step ' .. n .. ': ' .. key)
end
end
if next(ratios) ~= nil then
if next(ratios) ~= nil then
local consistent = p.additively_consistent(equave, size, ratios, distinct, previous)
local consistent = p.additively_consistent(et, ratios, distinct, previous)
if not consistent then
if not consistent then
return last_n
return last_n