Module:Limits: Difference between revisions

Plumtree (talk | contribs)
Distinct consistency limit: bugfix
Sintel (talk | contribs)
merge changes from dev
Line 1: Line 1:
local rat = require('Module:Rational')
local rat = require("Module:Rational")
local ET = require('Module:ET')
local ET = require("Module:ET")
local p = {}
local p = {}


Line 13: Line 13:
a = rat.modulo_mul(a, equave)
a = rat.modulo_mul(a, equave)
local a_key = rat.as_ratio(a)
local a_key = rat.as_ratio(a)
 
local b = rat.new(q, n)
local b = rat.new(q, n)
b = rat.modulo_mul(b, equave)
b = rat.modulo_mul(b, equave)
local b_key = rat.as_ratio(b)
local b_key = rat.as_ratio(b)
 
if previous[a_key] == nil then
if previous[a_key] == nil then
ratios[a_key] = a
ratios[a_key] = a
Line 41: Line 41:
-- if a function `norm` and a number `max_norm` are provided, the output will be additionally restricted
-- if a function `norm` and a number `max_norm` are provided, the output will be additionally restricted
function p.integer_limit(q, norm, max_norm)
function p.integer_limit(q, norm, max_norm)
local check_norm = type(norm) == 'function' and type(max_norm) == 'number'
local check_norm = type(norm) == "function" and type(max_norm) == "number"
local ratios = {}
local ratios = {}
for n = 1, q do
for n = 1, q do
Line 68: Line 68:
if approx_set[a_approx] then
if approx_set[a_approx] then
if not rat.eq(rat.modulo_mul(rat.div(a, approx_set[a_approx]), et.equave), 1) then
if not rat.eq(rat.modulo_mul(rat.div(a, approx_set[a_approx]), et.equave), 1) then
mw.log(a_key .. ' -> ' .. a_approx .. ': conflict!')
mw.log(a_key .. " -> " .. a_approx .. ": conflict!")
return false
return false
end
end
end
end
approx_set[a_approx] = a
approx_set[a_approx] = a
mw.log(a_key .. ' -> ' .. a_approx)
mw.log(a_key .. " -> " .. a_approx)
end
end
for a_key, a in pairs(ratios) do
for a_key, a in pairs(ratios) do
Line 79: Line 79:
if approx_set[a_approx] then
if approx_set[a_approx] then
if not rat.eq(rat.modulo_mul(rat.div(a, approx_set[a_approx]), et.equave), 1) then
if not rat.eq(rat.modulo_mul(rat.div(a, approx_set[a_approx]), et.equave), 1) then
mw.log(a_key .. ' -> ' .. a_approx .. ': conflict!')
mw.log(a_key .. " -> " .. a_approx .. ": conflict!")
return false
return false
end
end
end
end
approx_set[a_approx] = a
approx_set[a_approx] = a
mw.log(a_key .. ' -> ' .. a_approx)
mw.log(a_key .. " -> " .. a_approx)
end
end
end
end
if type(distinct) == 'number' then
if type(distinct) == "number" then
return true
return true
end
end
local previous_ordered = {}
local previous_ordered = {}
for a_key, a in pairs(previous) do
for _, a in pairs(previous) do
table.insert(previous_ordered, a)
table.insert(previous_ordered, a)
end
end
local ratios_ordered = {}
local ratios_ordered = {}
for a_key, a in pairs(ratios) do
for _, a in pairs(ratios) do
table.insert(ratios_ordered, a)
table.insert(ratios_ordered, a)
end
end
for i, a in ipairs(ratios_ordered) do
for i, a in ipairs(ratios_ordered) do
local a_approx = ET.approximate(et, rat.as_float(a))
local a_approx = ET.approximate(et, rat.as_float(a))
for j, b in ipairs(previous_ordered) do
for _, b in ipairs(previous_ordered) do
local b_approx = ET.approximate(et, rat.as_float(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 = ET.approximate(et, rat.as_float(c))
local c_approx = ET.approximate(et, rat.as_float(c))
 
c = rat.modulo_mul(c, et.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
if c_approx ~= a_approx + b_approx then
if c_approx ~= a_approx + b_approx then
mw.log('a = ' .. rat.as_ratio(a) .. '; b = ' .. rat.as_ratio(b) .. '; ab = ' .. c_key)
mw.log("a = " .. rat.as_ratio(a) .. "; b = " .. rat.as_ratio(b) .. "; ab = " .. c_key)
mw.log(a_approx .. ' + ' .. b_approx .. ' != ' .. c_approx)
mw.log(a_approx .. " + " .. b_approx .. " != " .. c_approx)
return false
return false
end
end
Line 119: Line 119:
if i <= j then
if i <= j then
local b_approx = ET.approximate(et, rat.as_float(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 = ET.approximate(et, rat.as_float(c))
local c_approx = ET.approximate(et, rat.as_float(c))
 
c = rat.modulo_mul(c, et.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
if c_approx ~= a_approx + b_approx then
if c_approx ~= a_approx + b_approx then
mw.log('a = ' .. rat.as_ratio(a) .. '; b = ' .. rat.as_ratio(b) .. '; ab = ' .. c_key)
mw.log("a = " .. rat.as_ratio(a) .. "; b = " .. rat.as_ratio(b) .. "; ab = " .. c_key)
mw.log(a_approx .. ' + ' .. b_approx .. ' != ' .. c_approx)
mw.log(a_approx .. " + " .. b_approx .. " != " .. c_approx)
return false
return false
end
end
Line 145: Line 145:
if et.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
distinct = distinct or false
distinct = distinct or false
local n = 1
local n = 1
Line 153: Line 153:
local previous = {}
local previous = {}
while true do
while true do
if type(distinct) == 'number' and n > distinct then
if type(distinct) == "number" and n > distinct then
return last_n
return last_n
end
end
local ratios = p.limit_modulo_equave(n, et.equave, previous)
local ratios = p.limit_modulo_equave(n, et.equave, previous)
for key, ratio in pairs(ratios) do
for key, _ 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(et, ratios, distinct, previous)
local consistent = p.additively_consistent(et, ratios, distinct, previous)
if not consistent then
if not consistent then
mw.log('Not consistent at step ' .. n .. ', returning ' .. last_n)
mw.log("Not consistent at step " .. n .. ", returning " .. last_n)
return last_n
return last_n
end
end