  lua-l archive

• Subject: Re: Fun math puzzle: cin(X)
• From: Egor Skriptunoff <egor.skriptunoff@...>
• Date: Fri, 5 Apr 2019 00:25:14 +0300

On Thu, Apr 4, 2019 at 2:14 AM Albert Chan wrote:
Comes across a fun math puzzle. :-)
Design a function cin(X), such that cin(cin(cin(X))) = sin(X)

The most straightforward approach is
to build Taylor series of cin(x) one term at a time.

local maclaurin_of_cin
do
local c, d, s, a = { = 1}, { = 1}, 1

local function g(k, m)
if k == 0 or m < 0 then
return m == 0 and 1 or 0
else
local i = k..";"..m
local r = a[i]
if not r then
r = 0
for j = 0, #c do
r = r + c[j] * g(k-1, m-j)
end
a[i] = r
end
return r
end
end

local function f(o)
local r = 0
for j = 0, #c do
r = r + o[j] * g(2*j+1, #c+1-j)
end
return r
end

function maclaurin_of_cin(k)
for n = #c + 1, k do
a = {}
local e, h = f(c), f(d)
s, a = -s/(2*n)/(2*n+1)
local t = (s-h-e)/3
assert(math.abs(t) < 0.056)
c[n], d[n] = t, e + 2*t
end
return c[k]
end
end

local function cin(x)
local r, p, s, n, R = x, x, x*x, 0
repeat
R, n, p = r, n+1, p*s
r = r + maclaurin_of_cin(n) * p
until r == R
return r
end

-- (-0.7) < x < 0.7
local x = 0.7
print("x                = "..x)
print("cin(x)           = "..cin(x))
print("cin(cin(x))      = "..cin(cin(x)))
print("cin(cin(cin(x))) = "..cin(cin(cin(x))))
print("sin(x)           = "..math.sin(x))

This implementation works only if x is in the range from (-0.7) to (+0.7)
That's because of floating point arithmetic is approximate.
Exact arithmetic of fractions (with arbitrary long numerator and denominator) must be used instead.