145 lines
4.4 KiB
Lua
145 lines
4.4 KiB
Lua
--Bespoke script for calculating one-parameter family of real analytic solutions
|
|
--to functional equation f'( f( x ) ) = x.
|
|
|
|
--Idea: suppose f has fixed point 'p',
|
|
--apply the chain rule to functional equation
|
|
--get values of f's derivatives at p
|
|
--get truncated taylor series expansion of f at p
|
|
--plot to get some idea about values, convergence.
|
|
|
|
local plot = {
|
|
x = 0,
|
|
X = 1,
|
|
y = 0,
|
|
Y = 1,
|
|
dx = 0.001,
|
|
dy = 0.001,
|
|
inverse = false,
|
|
fdbOrder = 50,}
|
|
|
|
plot.Zoom = function( zoomFactor )
|
|
|
|
plot.dx, plot.dy = plot.dx * zoomFactor, plot.dy * zoomFactor
|
|
|
|
local cx, cy = 0.5 * ( plot.x + plot.X ), 0.5 * ( plot.y + plot.Y )
|
|
local lx, ly = zoomFactor * 0.5 * ( plot.X - plot.x ), zoomFactor * 0.5 * ( plot.Y - plot.y )
|
|
plot.x, plot.X = cx - lx, cx + lx
|
|
plot.y, plot.Y = cy - ly, cy + ly
|
|
end
|
|
|
|
plot.Translate = function( x, y )
|
|
x = 0.01 * (plot.X - plot.x) * x
|
|
y = 0.01 * (plot.Y - plot.y) * y
|
|
plot.x, plot.X = plot.x + x, plot.X + x
|
|
plot.y, plot.Y = plot.y + y, plot.Y + y
|
|
end
|
|
|
|
local FaaDiBruno = require( 'fdb' )
|
|
local Ansatz = require( 'ansatz' )
|
|
local Poly = require( 'interpolant' )
|
|
|
|
local a = 1.619
|
|
local function PlotFunction( f, color )
|
|
|
|
local points = {}
|
|
local n = 1
|
|
for x = plot.x - 0.1, plot.X + 0.1, plot.dx do
|
|
points[ 2 * n - 1 ] = x
|
|
points[ 2 * n ] = f( x )
|
|
n = n + 1
|
|
|
|
end
|
|
|
|
--inverse
|
|
local inverse = {}
|
|
for i = 1, n, 2 do
|
|
inverse[i], inverse[i + 1] = points[ i + 1], points[i]
|
|
end
|
|
|
|
|
|
local x, y = love.graphics.getDimensions()
|
|
love.graphics.setLineWidth( 0.1 )
|
|
love.graphics.setLineJoin( "miter" )
|
|
love.graphics.setLineStyle( "smooth" )
|
|
local draw = love.draw or function() end
|
|
|
|
love.draw = function()
|
|
draw()
|
|
love.graphics.push("transform")
|
|
love.graphics.translate( 0, y )
|
|
love.graphics.scale( x, -y )
|
|
love.graphics.scale( 1 / (plot.X - plot.x), 1/ (plot.Y - plot.y) )
|
|
love.graphics.translate( - plot.x, - plot.y )
|
|
love.graphics.setLineWidth( 0.003 * (plot.X - plot.x) )
|
|
|
|
love.graphics.setColor( 0.5, 0.5, 0.5, 0.3 )
|
|
love.graphics.line( -10, -10, 10, 10 )
|
|
love.graphics.line( -10, 0, 10, 0 )
|
|
love.graphics.line( 0, -10, 0, 10 )
|
|
|
|
if color then love.graphics.setColor( color ) end
|
|
love.graphics.line( plot.inverse and inverse or points )
|
|
|
|
love.graphics.circle( "fill", a, a, 0.003 * (plot.X - plot.x) )
|
|
love.graphics.pop()
|
|
|
|
|
|
love.graphics.setFont( love.graphics.getFont( 48 ) )
|
|
love.graphics.print( a )
|
|
love.graphics.print( plot.fdbOrder, 0, 15 )
|
|
love.graphics.print( f(a), 0, 30 )
|
|
love.graphics.print( f(-1.0), 0, 45 )
|
|
love.graphics.setColor( 1,1,1,1 )
|
|
end
|
|
|
|
end
|
|
|
|
love.wheelmoved = function( x, y )
|
|
return plot.Zoom( (y > 0) and 0.95 or 1.05 ) or love.keypressed()
|
|
end
|
|
|
|
love.mousepressed = function(x, y, button)
|
|
plot.inverse = not( plot.inverse )
|
|
plot.fdbOrder = plot.fdbOrder + (( button == 1 ) and 1 or -1 )
|
|
return love.keypressed()
|
|
end
|
|
|
|
--[[local f, df = Poly( FaaDiBruno( a ) )
|
|
PlotFunction( f, {1, 0, 0, 0.5} ) --Function
|
|
PlotFunction( df, {0, 1, 0, 0.5} ) --First derivative
|
|
PlotFunction( function(x) return x end, {0, 0, 1, 0.5})]]
|
|
|
|
love.keypressed = function( key, code )
|
|
if code == "q" then a = a + 0.001 * (plot.X - plot.x) end
|
|
if code == "e" then a = a - 0.001 * (plot.X - plot.x) end
|
|
if code == "w" then plot.Translate( 0, 1 ) end
|
|
if code == "a" then plot.Translate( -1, 0 ) end
|
|
if code == "s" then plot.Translate( 0, -1 ) end
|
|
if code == "d" then plot.Translate( 1, 0 ) end
|
|
if code == "z" then plot.Zoom( 0.95 ) end
|
|
if code == "c" then plot.Zoom( 1.05 ) end
|
|
if code == "f" then plot.fdbOrder = plot.fdbOrder - 1 end
|
|
if code == "r" then plot.fdbOrder = plot.fdbOrder + 1 end
|
|
love.draw = nil
|
|
|
|
local f, df, fn = Poly( FaaDiBruno( a, plot.fdbOrder ) )
|
|
PlotFunction( f, {1, 0, 0, 0.7} ) --Function in red.
|
|
PlotFunction( df, {0, 1, 0, 0.7} ) --First derivative in green.
|
|
|
|
--PlotFunction( function(x) return df( f ( x ) ) end, {0, 0, 1, 0.3})
|
|
--PlotFunction( function(x) return f( df ( x ) ) end, {1, 1, 1, 0.3})
|
|
--PlotFunction( function(x) return x end, {1, 1, 1, 0.3})
|
|
local af, an = Poly( Ansatz.coefs )
|
|
--PlotFunction( af, {1,1,1, 0.3} )
|
|
--PlotFunction( an, {1,1,1, 0.3} )
|
|
PlotFunction( Ansatz.dpo, {1, 1, 1, 0.3} )
|
|
PlotFunction( Ansatz.pos, {1,1,1,0.3} )
|
|
end
|
|
|
|
love.update = function( dt )
|
|
for _, code in ipairs{ 'q', 'e', 'w', 'a', 's', 'd', 'z', 'c', 'f', 'r' } do
|
|
if love.keyboard.isScancodeDown( code ) then love.keypressed( nil, code ) end
|
|
end
|
|
end
|
|
|
|
love.keypressed( nil, nil ) |