• Subject: Re: Fun math puzzle: cin(X)
• From: Egor Skriptunoff <egor.skriptunoff@...>
• Date: Tue, 9 Apr 2019 23:05:58 +0300

On Tue, Apr 9, 2019 at 1:09 AM Albert Chan wrote:

> The most straightforward approach is
> to build Taylor series of cin(x) one term at a time.
>
>    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

Say, I wanted a function, din(x), such that din(din(din(din(x)))) = sin(x)

I don't use smart methods like Newton's (mentioned by Dirk).
My implementation is dumb and straightforward.
I solve trivially constructed system of equations to find Tailor coefficients of din().
(I simply substitute one Tailor series into another.)
If n first coefficients are already known, the formula for the (n+1)-th one is not very complex.

local maclaurin_of_din
do
local c, d, s, a = {[0] = 1}, {[0] = 1}, 1

local function g(k, m, o)
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, #o do
r = r + o[j] * g(k-1, m-j, o)
end
a[i] = r
end
return r
end
end

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

function maclaurin_of_din(k)
for n = #c + 1, k do
local e, h = f(c), f(d)
s = -s/(2*n)/(2*n+1)
local t = (s-h-2*e)/4
assert(t*t < 1)
c[n], d[n] = t, e + 2*t
end
return c[k]
end
end

local function din(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_din(n) * p
until r == R
return r
end

local x = 0.7
print("x                     = "..x)
print("din(x)                = "..din(x))
print("din(din(x))           = "..din(din(x)))
print("din(din(din(x)))      = "..din(din(din(x))))
print("din(din(din(din(x)))) = "..din(din(din(din(x)))))
print("sin(x)                = "..math.sin(x))