Module:Rational: Difference between revisions
convergents() implemented |
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 | ||