Module:Rational: Difference between revisions

Plumtree (talk | contribs)
convergents() implemented
Plumtree (talk | contribs)
m converges() implemented
Line 38: Line 38:
end
end


-- create a rational number from continued fraction array
function p.from_continued_fraction(data)
function p.from_continued_fraction(data)
local val = p.new(1, 0)
local val = p.new(1, 0)
Line 46: Line 47:
end
end


-- list convergents to `x` with a given stop condition
-- `stop` is either a number or a function of rational numbers
function p.convergents(x, stop)
function p.convergents(x, stop)
local convergents = {}
local convergents = {}
Line 65: Line 68:
end
end
return convergents
return convergents
end
-- determine whether a rational number is a convergent or a semiconvergent to `x`
function p.converges(a, x)
local n_a, m_a = p.as_pair(a)
local convergents = p.convergents(
x,
function(b)
local n_b, m_b = p.as_pair(b)
return m_b >= m_a * 10000
end
)
for i, b in ipairs(convergents) do
if p.eq(a, b) then
return 'convergent'
end
end
local last_error = 1/0
for i = 2, #convergents - 1 do
last_error = math.abs(p.as_float(convergents[i]) - x)
local n_delta, m_delta = p.as_pair(convergents[i])
local n_c, m_c = p.as_pair(convergents[i - 1])
while true do
n_c = n_c + n_delta
m_c = m_c + m_delta
local c = p.new(n_c, m_c)
if p.as_table(c)[2] >= p.as_table(convergents[i + 1])[2] then
break
end
local c_error = math.abs(p.as_float(c) - x)
if c_error < last_error then
last_error = c_error
if p.eq(a, c) then
return 'semiconvergent'
end
end
end
end
return false
end
end