Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- This file: -- http://angg.twu.net/LUA/Piecewise1.lua.html -- http://angg.twu.net/LUA/Piecewise1.lua -- (find-angg "LUA/Piecewise1.lua") -- Author: Eduardo Ochs <eduardoochs@gmail.com> -- -- (defun e () (interactive) (find-angg "LUA/Piecewise1.lua")) -- Piecewise functions, version for Pict2e1.lua. -- See: (find-angg "LUA/Pict2e1.lua") -- (find-angg "LUA/Pict2e1-1.lua") -- (find-LATEX "2022pict2e.lua" "PwSpec") -- -- (defun a () (interactive) (find-angg "LUA/Pict2e1.lua")) -- (defun b () (interactive) (find-angg "LUA/Piecewise1.lua")) -- (defun ab () (interactive) (find-2b '(a) '(b))) -- (defun et () (interactive) (find-angg "LATEX/2022pict2e.tex")) -- (defun eb () (interactive) (find-angg "LATEX/2022pict2e-body.tex")) -- (defun ao () (interactive) (find-angg "LATEX/2022pict2e.lua")) -- (defun v () (interactive) (find-pdftools-page "~/LATEX/2022pict2e.pdf")) -- (defun tb () (interactive) (find-ebuffer (eepitch-target-buffer))) -- (defun etv () (interactive) (find-wset "13o2_o_o" '(tb) '(v))) -- (setenv "PICT2ELUADIR" "~/LATEX/") -- (find-LATEXgrep "grep --color=auto -niH --null -e piecewise *.tex *.lua") require "Pict2e1" -- (find-angg "LUA/Pict2e1.lua") require "Pict2e1-1" -- (find-angg "LUA/Pict2e1-1.lua") -- «.PwSpec» (to "PwSpec") -- «.PwSpec-test1» (to "PwSpec-test1") -- «.PwSpec-test2» (to "PwSpec-test2") -- «.PwSpec-testmtint» (to "PwSpec-testmtint") -- «.PwFunction» (to "PwFunction") -- «.PwFunction-Riemann» (to "PwFunction-Riemann") -- «.PwFunction-tests» (to "PwFunction-tests") -- «.PwFunction-testpoles» (to "PwFunction-testpoles") -- «.PwFunction-intfig» (to "PwFunction-intfig") -- «.Partition» (to "Partition") -- «.Partition-tests» (to "Partition-tests") -- «.Riemann» (to "Riemann") -- «.Riemann-tests» (to "Riemann-tests") -- «.Riemann-tests-sc» (to "Riemann-tests-sc") -- «.TFC1» (to "TFC1") -- «.TFC1-tests» (to "TFC1-tests") -- «.Xtoxytoy» (to "Xtoxytoy") -- «.Xtoxytoy-test1» (to "Xtoxytoy-test1") -- «.Xtoxytoy-test2» (to "Xtoxytoy-test2") -- «.Xtoxytoy-test3» (to "Xtoxytoy-test3") -- «.ChangeVar» (to "ChangeVar") -- «.ChangeVar-test1» (to "ChangeVar-test1") -- ____ ____ -- | _ \__ __/ ___| _ __ ___ ___ -- | |_) \ \ /\ / /\___ \| '_ \ / _ \/ __| -- | __/ \ V V / ___) | |_) | __/ (__ -- |_| \_/\_/ |____/| .__/ \___|\___| -- |_| -- -- «PwSpec» (to ".PwSpec") -- A "spec" for a piecewise function is something like this: -- -- "(0,1)c--(2,3)o (2,2)c (2,1)o--(4,1)--(5,2)" -- -- Note that its segments can be non-horizontal. -- -- An object of this class starts with a spec, immediately calculates -- its lists of "dxyoc"s, and from that it can generate lots of other -- data. The list of "dxyoc"s for the spec above is: -- -- PwSpec.from("(0,1)c--(2,3)o (2,2)c (2,1)o--(4,1)--(5,2)").dxyocs -- = { {"dash"="" , "x"=0, "y"=1, "oc"="c"}, -- {"dash"="-", "x"=2, "y"=3, "oc"="o"}, -- {"dash"="" , "x"=2, "y"=2, "oc"="c"}, -- {"dash"="" , "x"=2, "y"=1, "oc"="o"}, -- {"dash"="-", "x"=4, "y"=1, "oc"="" }, -- {"dash"="-", "x"=5, "y"=2, "oc"="" } } -- PwSpec = Class { type = "PwSpec", from = function (src) return PwSpec({src=src, dxyocs={}}):add(src) end, fromep = function (spec0) -- ep means "eval, topict" local exprang = function (str) return expr(str:sub(2,-2)) end local spec = spec0:gsub("%b<>", exprang) local pws = PwSpec.from(spec) local p = pws:topict() if color then p = p:Color(color) end return p end, dxyoc_to_string = function (dxyoc) return format("%s(%s,%s)%s", (dxyoc.dash == "-" and "--" or " "), dxyoc.x, dxyoc.y, dxyoc.oc or "") end, __tostring = function (pws) return pws:tostring() end, __index = { npoints = function (pw) return #pw.points end, -- -- Add points and segments. -- Example: pws:add("(0,1)o--(1,1)o (1,2)c (1,3)o--(2,3)c--(3,2)--(4,2)c") add = function (pws, str) local patn = "%s*([-+.%d]+)%s*" local pat = "(%-?)%("..patn..","..patn.."%)([oc]?)" for dash,x,y,oc in str:gmatch(pat) do table.insert(pws.dxyocs, {dash=dash, x=x+0, y=y+0, oc=oc}) end return pws end, -- tostring = function (pws) return mapconcat(PwSpec.dxyoc_to_string, pws.dxyocs, "") end, -- -- Express a piecewise function as a Lua function. conds_tbl = function (pws) local conds = {} for i=1,#pws.dxyocs do local P0,P1,P2 = pws.dxyocs[i], pws.dxyocs[i+1], pws.dxyocs[i+2] local p0,p1,p2 = P0, P1 or {}, P2 or {} local x0,y0,oc0 = p0.x, p0.y, p0.oc local x1,y1,oc1,dash1 = p1.x, p1.y, p1.oc, p1.dash local x2,y2,oc2,dash2 = p2.x, p2.y, p2.oc, p2.dash if oc0 ~= "o" then local cond = format("(%s == x) and %s", x0, y0) table.insert(conds, cond) end if dash1 == "-" then local cond = format("(%s < x and x < %s)", x0, x1) if y1 == y0 then cond = format("%s and %s", cond, y0) else cond = format("%s and (%s + (x - %s)/(%s - %s) * (%s - %s))", cond, y0, x0, x1, x0, y1, y0 ) end table.insert(conds, cond) end end return conds end, conds = function (pws) return table.concat(pws:conds_tbl(), " or\n") end, fun0 = function (pws) return "function (x) return (\n"..pws:conds().."\n) end" end, fun = function (pws) return expr(pws:fun0()) end, -- -- Get lines and open/closed points, for drawing. getj = function (pws, i) return (pws.dxyocs[i+1] and (pws.dxyocs[i+1].dash == "-") and pws:getj(i+1)) or i end, getijs = function (pws) local i, j, ijs = 1, pws:getj(1), {} while true do if i < j then table.insert(ijs, {i, j}) end i = j + 1 j = pws:getj(i) if #pws.dxyocs < i then return ijs end end end, getpoint = function (pws, i) return v(pws.dxyocs[i].x, pws.dxyocs[i].y) end, getpoints = function (pws, i, j) local ps = Points2.new() for k=i,j do ps:add(pws:getpoint(k)) end return ps end, topict = function (pws) cmds = PictList {} for _,ij in ipairs(pws:getijs()) do cmds:addobj(pws:getpoints(ij[1], ij[2]):Line()) end for i,p in ipairs(pws.dxyocs) do if p.oc == "o" then cmds:addopendotat(pws:getpoint(i)) elseif p.oc == "c" then cmds:addcloseddotat(pws:getpoint(i)) end end return cmds end, -- topwfunction = function (pws) local spec,f = pws.src, pws:fun() local pwf = PwFunction.from(f) for x,y in spec:gmatch("%( *([-.0-9]+) *, *([-.0-9]+) *%)") do pwf:addpoint(tonumber(x)) end return pwf end, }, } -- «PwSpec-test1» (to ".PwSpec-test1") --[==[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Piecewise1.lua" spec = "(0,1)c--(2,3)o (2,2)c (2,1)o--(4,1)--(5,2)" PPPV(PwSpec.from(spec).dxyocs) spec = "(0,1)o--(1,1)o (1,4)c (1,3)o--(2,3)c--(3,2)--(4,2)c" spec = "(0,1)c--(2,3)o (2,2)c (2,1)o--(4,1)c" pws = PwSpec.from(spec) = pws = pws:conds() = pws:fun0() = pws:topict() = pws:topict():bshow() * (etv) f = pws:fun() = f(0.1) = f(1.9) = f(2) = f(2.1) = f(2.2) --]==] -- «PwSpec-test2» (to ".PwSpec-test2") --[[ -- (c2m212isp 11 "uma-figura") -- (c2m212isa "uma-figura") -- (c2m221isp 2 "uma-figura") -- (c2m221isa "uma-figura") * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Piecewise1.lua" fromep = PwSpec.fromep thick = function (th) return "\\linethickness{"..th.."}" end putcellat = function (xy, str) return pformat("\\put%s{\\cell{%s}}", xy, str) end = fromep("(0,0)--(2,<1+2>)c") = putcellat(v(2,3), "foo") _minfy,_pinfy = -3,10 _xD,_xL,_xU = -0.4,-0.8,-1.0 p = PictList { fromep(" (0,<_pinfy-1>)--(0,<_pinfy>)c "), fromep(" (0,<_minfy+1>)--(0,<_minfy>)c "), putcellat(v(1.2, _pinfy), "+\\infty"), putcellat(v(1.2, _minfy), "-\\infty"), thick("1pt"), fromep(" (-1,2)--(3,6)--(8,1)--(11,4) "), thick("2pt"), fromep(" (1,0)c--(2,0)c "):color("red"), fromep(" (1,4)c--(2,5)c "):color("orange"), fromep(" (0,4)c--(0,5)c "):color("green"), fromep(" (<_xL>,<_minfy>)c--(<_xL>,4)c "):color("blue"), fromep(" (<_xD>,4)c--(<_xD>,5)c "):color("SpringDarkHard"), fromep(" (<_xU>,5)c--(<_xU>,<_pinfy>)c "):color("violet"), } p = (p :setbounds(v(-1,0), v(11,7)) :pgat("gat") :setbounds(v(-1,_minfy), v(11,_pinfy)) :pgat("p") :preunitlength("15pt") :scalebox("0.8") ) = Show.try(p:tostringp()) * (etv) --]] -- «PwSpec-testmtint» (to ".PwSpec-testmtint") -- (c2m221mt1p 2 "defs-figuras") -- (c2m221mt1a "defs-figuras") --[==[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Piecewise1.lua" hx = function (x, y) return format(" (%s,%s)c--(%s,%s)o", x-1,y, x,y) end hxs = function (...) local str = "" for x,y in ipairs({...}) do str = str .. hx(x, y) end return str end mtintegralspec = function (specf, xmax, y0) local pws = PwSpec.from(specf) local f = pws:fun() local ys = {[0] = y0} for x=1,xmax do ys[x] = ys[x - 1] + f(x - 0.5) end local strx = function (x) return tostring(v(x, ys[x])) end local specF = mapconcat(strx, seq(0, xmax), "--") return specF end = hxs(1, 2, -1) specf = "(0,1)--(1,1)c (1,2)o--(3,2)o (3,-1)c--(4,-1)" specF = mtintegralspec(specf, 4, -2) pwsf = PwSpec.from(specf) pwsF = PwSpec.from(specF) pf = pwsf:topict():setbounds(v(0,-2), v(4,3)):pgat("pgat") pF = pwsF:topict():setbounds(v(0,-2), v(4,3)):pgat("pgat") p = PictList { pf, "\\quad", pF } = Show.try(p:tostringp()) * (etv) --]==] -- ____ _____ _ _ -- | _ \__ _| ___| _ _ __ ___| |_(_) ___ _ __ -- | |_) \ \ /\ / / |_ | | | | '_ \ / __| __| |/ _ \| '_ \ -- | __/ \ V V /| _|| |_| | | | | (__| |_| | (_) | | | | -- |_| \_/\_/ |_| \__,_|_| |_|\___|\__|_|\___/|_| |_| -- -- «PwFunction» (to ".PwFunction") -- An object of the class PwFunction starts with a function and with -- its sets of "important points", and it can produce lots of data -- from that. -- -- The most typical use of "PwFunction" is like this: -- -- f = function (x) if x < 2 then return x^2 else return 2 end end -- pwf = PwFunction.from(f, seq(0, 2, 0.5), 4) -- pict = pwf:pw(1, 3) -- pict:bshow() -- -- We convert the function f (plus its important points) to a -- PwFunction, and then we generate a PwSpec that draws its graph in a -- certain interval, and we convert that PwSpec to a Pict2e object and -- we draw it. Note that the method ":pw(...)" does two conversions: -- -- PwFunction -> PwSpec -> Pict2e -- PwFunction = Class { type = "PwFunction", from = function (f, ...) return PwFunction({f=f}):setpoints(...) end, __index = { -- -- The "important points" are stored in a "Set". -- Example: pwf:setpoints(seq(0, 4, 0.25), 5, 6, 7) setpoints = function (pwf, ...) pwf.points = Set.new() -- (find-angg "LUA/lua50init.lua" "Set") return pwf:addpoints(...) end, addpoints = function (pwf, ...) for _,o in ipairs({...}) do if type(o) == "number" then pwf:addpoint(o) elseif type(o) == "table" then pwf:addlistofpoints(o) else PP("not a point or a list of points:", o); error() end end return pwf end, addpoint = function (pwf, p) if type(p) ~= "number" then PP("Not a number:", p); error() end pwf.points:add(p) return pwf end, addlistofpoints = function (pwf, A) for _,p in ipairs(A) do pwf:addpoint(p) end return pwf end, -- -- All important points in the interval (a,b). pointsin = function (pwf, a, b) local A = {} for _,x in ipairs(pwf.points:ks()) do if a < x and x < b then table.insert(A, x) end end return A end, -- -- Detect discontinuities using a heuristic. eps = 1/32768, delta = 1/128, hasjump = function (pwf, x0, x1) local y0,y1 = pwf.f(x0), pwf.f(x1) return math.abs(y1-y0) > pwf.delta end, hasjumpl = function (pwf, x) return pwf:hasjump(x - pwf.eps, x) end, hasjumpr = function (pwf, x) return pwf:hasjump(x, x + pwf.eps) end, -- xy = function (pwf, x, y) return pformat("(%s,%s)", x, y or pwf.f(x)) end, xyl = function (pwf, xc) return pwf:xy(xc - pwf.eps) end, xyr = function (pwf, xc) return pwf:xy(xc + pwf.eps) end, jumps_and_xys = function (pwf, xc) local xyl, xyc, xyr = pwf:xyl(xc), pwf:xy(xc), pwf:xyr(xc) local jumpl = pwf:hasjumpl(xc) and "l" or "" local jumpr = pwf:hasjumpr(xc) and "r" or "" local jumps = jumpl..jumpr -- "lr", "l", "r", or "" return jumps, xyl, xyc, xyr end, -- xym = function (pwf, xc) local jumps, xyl, xyc, xyr = pwf:jumps_and_xys(xc) if jumps == "" then str = xyc elseif jumps == "l" then str = format("%so %sc", xyl, xyc) elseif jumps == "r" then str = format( "%sc %so", xyc, xyr) elseif jumps == "lr" then str = format("%so %sc %so", xyl, xyc, xyr) end return str end, -- piecewise_m = function (pwi, xc) -- "m" is for "middle" local jumps, xyl, xyc, xyr = pwi:jumps_and_xys(xc) if jumps == "" then str = xyc elseif jumps == "l" then str = format("%so %sc", xyl, xyc) elseif jumps == "r" then str = format("%sc %so", xyc, xyr) elseif jumps == "lr" then str = format("%so %sc %so", xyl, xyc, xyr) end return str end, piecewise = function (pwi, a, b, method, sep) local method, sep = method or "piecewise_m", sep or "--" local f = function (x) return pwi[method](pwi, x) end local str = pwi:xyr(a) -- for _,x in ipairs(pwi.points:ks()) do -- if a < x and x < b then -- str = str..sep..f(x) -- end -- end for _,x in ipairs(pwi:pointsin(a, b)) do str = str..sep..f(x) end str = str..sep..pwi:xyl(b) return str end, pw = function (pwi, a, b) return pictpiecewise(pwi:piecewise(a, b)) end, -- -- pwf:pwspec(a, b) converts a pwf to a "piecewise spec". -- This is tricky, so let's see an example. Suppose that: -- -- pwf:pointsin(a, b) = {c}. -- -- Then in the simplest case pwf:piecewise(a, b) would generate a -- piecewise spec like this, -- -- "(a,f(a))--(c,f(c))--(b,f(b))" -- -- but we have tricks for dealing with discontinuites and drawing -- closed dots and open dots... for example, we can generate -- something like this: -- -- "(a,f(a))--(c-eps,f(c-eps))o (c,f(c))c--(b,f(b))" -- -- The hard work to convert c to -- -- "(c-eps,f(c-eps))o (c,f(c))c" -- -- is done by the function xym, defined above; the case "_o _c" -- corresponds to jumps == "l". Note that the "eps"s usually -- disappear when each coordinate of the "(x,y)"s is rounded to at -- most three decimals. -- -- Btw, I think that the extremities are "(a+eps,f(a+eps))" and -- "(b-eps,f(b+eps))", not "(a,f(a))" and "(b,f(b))"... TODO: -- check that. -- -- Btw 2: pwf:pwspec(...) can generate other kinds of output if -- it is called with the right hackish optional arguments. -- pwspec = function (pwf, a, b, method, sep) local method = method or "xym" local sep = sep or "--" local xym = function (x) return pwf[method](pwf, x) end local str -- -- Add points (including discontinuities) and "--"s to str. str = pwf:xyr(a) for _,x in ipairs(pwf:pointsin(a, b)) do str = str..sep..xym(x) end str = str..sep..pwf:xyl(b) return str end, -- -- :pw(a,b) generates a Pict2e object that -- draws f in the interval [a,b]. pw = function (pwf, a, b) return PwSpec.from(pwf:pwspec(a, b)):topict() end, -- -- -- -- Methods that call pwspec in hackish ways. -- TODO: fix names, write tests. -- -- :lineify(...) and :areaify(...) only work when -- there are no discontinuities. FIX THIS! -- lineify00 = function (pwf, a, b) -- new, 2022jun16 local ps = Points2.new() local addp = function (x) ps:add(v(x, pwf.f(x))) end local hasjump = function (xl, xr) return pwf:hasjump(xl, xr) end local e = pwf.eps if hasjump(a, a+e) then addp(a+e) else addp(a) end for _,x in ipairs(pwf:pointsin(a, b)) do if hasjump(x-e, x+e) then addp(x-e); addp(x+e) else addp(x) end end if hasjump(b-e, b) then addp(b-e) else addp(b) end return ps end, lineify0 = function (pwf, a, b) return pwf:piecewise(a, b, nil, "") end, lineify = function (pwf, a, b) return PictList { pformat("\\Line%s", pwf:lineify00(a, b)) } end, areaify = function (pwf, a, b) local ly = pwf:lineify0(a, b) local poly = pformat("%s%s%s", v(a,0), pwf:lineify00(a, b), v(b,0)) return PictList { "\\polygon*"..poly } end, }, } -- «PwFunction-tests» (to ".PwFunction-tests") --[[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Piecewise1.lua" f = function (x) if x < 2 then return x^2 else return 2 end end pwf = PwFunction.from(f, seq(0, 2, 0.5), 4) PPPV(pwf) spec = pwf:pwspec(0, 4) PPPV(spec) spec = pwf:pwspec(1, 3) PPPV(spec) pws = PwSpec.from(spec) PPPV(pws) pict = pws:topict() PPPV(pict) = pict f = function (x) if x < 2 then return x^2 else return 2 end end pwf = PwFunction.from(f, seq(0, 2, 0.5), 4) = pwf:lineify00(1.1, 3.1) = pwf:lineify(1.1, 3.1) = pwf:areaify(1.1, 3.1) = pwf:pwspec(0, 4) = pwf:pw (0, 4) = pwf:pwspec(1, 3) = pwf:pw (1, 3) = pwf:pw (1, 3):bshow() * (etv) = pwf:pw (0, 4):bshow() * (etv) * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Piecewise1.lua" Pict2e.bounds = PictBounds.new(v(0,0), v(8,5)) f_parabola_preferida = function (x) return 4 - (x-2)^2 end f_parabola_complicada = function (x) if x <= 4 then return f_parabola_preferida(x) end if x < 5 then return 5 - x end if x < 6 then return 7 - x end if x < 7 then return 3 end if x == 7 then return 4 end return 0.5 end pwf = PwFunction.from(f_parabola_complicada, seqn(0, 4, 32), seq(4, 8)) p = PictList { pwf:areaify(2, 6.5):Color("Orange"), pwf:pw(0, 8), } = p:bshow() * (etv) --]] -- (find-LATEX "2021-1-C2-critical-points.lua" "Approxer") -- (c2m212somas2p 42 "exercicio-16-defs") -- (c2m212somas2a "exercicio-16-defs") -- «PwFunction-testpoles» (to ".PwFunction-testpoles") -- New: (c2m221atisp 5 "x^-2") -- (c2m221atisa "x^-2") -- Old: (c2m212intsp 5 "x^-2") -- (c2m212intsa "x^-2") -- (find-es "maxima" "TFC2-fails") --[[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Piecewise1.lua" Pict2e.bounds = PictBounds.new(v(-4,-4), v(4,4)) plotdot = function (x, y) return PictList{}:addcloseddotat(v(x,y)) end trunc = function (y) return min(max(-4,y),4) end f = function (x) return x==0 and 4 or trunc(1/x^2) end F = function (x) return x==0 and 4 or trunc(-1/x) end pwf = PwFunction.from(f, seqn(-4, 4, 64)) pwF = PwFunction.from(F, seqn(-4, 4, 64)) = f(2) = F(2) p = PictList { pwf:areaify(-1, 1):Color("Orange"), pwf:pw(-4, -1/2), pwf:pw(1/2, 4), } = p:bshow() * (etv) p = PictList { pwF:pw(-4, -1/4), pwF:pw(1/4, 4), plotdot(-1, F(-1)), plotdot(1, F(1)) } = p:bshow() * (etv) --]] -- «PwFunction-intfig» (to ".PwFunction-intfig") -- Superseded by: (to "ChangeVar-test1") --[[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Piecewise1.lua" Pict2e.bounds = PictBounds.new(v(0,0), v(4,3)) pi, sqrt, sin, cos = math.pi, math.sqrt, math.sin, math.cos maxu = pi maxx = sqrt(maxu) fu = function (u) return math.sin(u) end fx = function (x) return math.sin(x^2) * 2*x end pwfu = PwFunction.from(fu, seqn(0, maxu, 64)) pwfx = PwFunction.from(fx, seqn(0, maxx, 64)) areau = function (a, b, color) return pwfu:areaify(a, b):color(color) end areax = function (a, b, color) return pwfx:areaify(sqrt(a), sqrt(b)):color(color) end areauorx = function(areaf) local p = PictList {} local colors = split("red orange yellow") local points = {0, 1, 2, 3} for i=1,#colors do table.insert(p, areaf(points[i], points[i+1], colors[i])) end return p end pu = PictList { areauorx(areau), pwfu:lineify(0, maxu), } px = PictList { areauorx(areax), pwfx:lineify(0, maxx), } pux = PictList { pu:pgat("pgatc"), "\\quad", px:pgat("pgatc"), } = Show.try(pux:dd():tostringp()) * (etv) } --]] -- ____ _ _ _ _ -- | _ \ __ _ _ __| |_(_) |_(_) ___ _ __ -- | |_) / _` | '__| __| | __| |/ _ \| '_ \ -- | __/ (_| | | | |_| | |_| | (_) | | | | -- |_| \__,_|_| \__|_|\__|_|\___/|_| |_| -- -- «Partition» (to ".Partition") Partition = Class { type = "Partition", new = function (a, b) return Partition {points={a,b}} end, __tostring = mytostringp, __index = { a = function (ptn) return ptn.points[1] end, b = function (ptn) return ptn.points[#ptn.points] end, N = function (ptn) return #ptn.points - 1 end, ai = function (ptn, i) return ptn.points[i] end, bi = function (ptn, i) return ptn.points[i+1] end, bminusa = function (ptn) return ptn:b() - ptn:a() end, splitn = function (ptn, N) local points = {} local Delta = ptn:bminusa() for k=0,N do table.insert(points, ptn:a() + Delta*(k/N)) end return Partition {points=points} end, }, } -- «Partition-tests» (to ".Partition-tests") --[[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Piecewise1.lua" = Partition.new(2, 10) = Partition.new(2, 10):splitn(4) = Partition.new(2, 10):splitn(4):N() ptn = Partition.new(2, 10):splitn(4) for i=1,ptn:N() do print(i, ptn:ai(i), ptn:bi(i)) end -- Use this do draw semicircles ptn = Partition { points={} } for _,theta in ipairs(seqn(math.pi, 0, 8)) do print(theta, math.cos(theta)) table.insert(ptn.points, math.cos(theta)) end = ptn --]] -- ____ _ -- | _ \(_) ___ _ __ ___ __ _ _ __ _ __ -- | |_) | |/ _ \ '_ ` _ \ / _` | '_ \| '_ \ -- | _ <| | __/ | | | | | (_| | | | | | | | -- |_| \_\_|\___|_| |_| |_|\__,_|_| |_|_| |_| -- -- «Riemann» (to ".Riemann") Riemann = Class { type = "Riemann", fromspec = function (spec) local pws = PwSpec.from(spec) local f = pws:fun() local pwf = PwFunction.from(f) for x,y in spec:gmatch("%( *([-.0-9]+) *, *([-.0-9]+) *%)") do pwf:addpoint(tonumber(x)) end return Riemann { spec=spec, f=f, pws=pws, pwf=pwf } end, frompwf = function (pwf) return Riemann { pwf=pwf, f=pwf.f } end, fromf = function (f, ...) local pwf = PwFunction.from(f, ...) return Riemann.frompwf(pwf) end, __tostring = mytostringvp, __index = { piecewise_pol1 = function (rie, xc) -- for polygons local jumps, xyl, xyc, xyr = rie.pwf:jumps_and_xys(xc) if jumps == "" then return xyc else return format("%s%s", xyl, xyr) end end, piecewise_pol = function (rie, a, b) local a0, b0 = rie.pwf:xy(a, 0), rie.pwf:xy(b, 0) return a0..pwi:piecewise(a, b, "piecewise_pol1", "")..b0 end, pol = function (rie, a, b, star) -- return "\\polygon"..(star or "")..pwi:piecewise_pol(a, b) return PictList { "\\polygon"..(star or "")..rie.pwf:piecewise_pol(a, b) } end, -- inforsup = function (rie, maxormin, a, b) local y = rie.f(a) local consider = function (x) y = maxormin(y, rie.f(x)) end consider(a + rie.pwf.eps) for _,x in ipairs(rie.pwf:pointsin(a, b)) do consider(x - rie.pwf.eps) consider(x) consider(x + rie.pwf.eps) end consider(b - rie.pwf.eps) consider(b) return y end, inf = function (rie, a, b) return rie:inforsup(min, a, b) end, sup = function (rie, a, b) return rie:inforsup(max, a, b) end, max = function (rie, a, b) return max(rie.f(a), rie.f(b)) end, min = function (rie, a, b) return min(rie.f(a), rie.f(b)) end, zero = function (rie) return 0 end, method = function (rie, mname, a, b) return rie[mname](rie, a, b) end, rct = function (rie, mname1, mname2, a, b) local y1 = rie:method(mname1, a, b) local y2 = rie:method(mname2 or "zero", a, b) return pformat("(%s,%s)(%s,%s)(%s,%s)(%s,%s)", a,y1, a,y2, b,y2, b,y1) end, rects = function (rie, ptn, mname1, mname2, star) local p = PictList {} for i=1,ptn:N() do local ai,bi = ptn:ai(i), ptn:bi(i) local rct = rie:rct(mname1, mname2, ai, bi) table.insert(p, format("\\polygon%s%s", star or "*", rct)) end return p end, -- setab = function (rie, a, b) rie.a = a; rie.b = b; return rie end, ptn = function (rie, N) return Partition.new(rie.a, rie.b):splitn(N) end, lineify = function (rie, a, b) return rie.pwf:lineify(a, b) end, areaify = function (rie) return rie.pwf:areaify(rie.a, rie.b) end, area = function (rie) return rie.pwf:areaify(rie.a, rie.b) end, areams = function (rie, N, mname1, mname2) return rie:rects(rie:ptn(N), mname1, mname2, "*") end, areainf = function (rie, N) return rie:areams(N, "zero", "inf") end, areasup = function (rie, N) return rie:areams(N, "zero", "sup") end, areainfsup = function (rie, N) return rie:areams(N, "inf", "sup") end, }, } -- «Riemann-tests» (to ".Riemann-tests") --[[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Piecewise1.lua" f = function (x) if x < 2 then return x^2 else return 2 end end rie = Riemann.fromf(f, seq(0, 4, 0.125)) = rie = rie.pwf = rie.pwf:pw(1,4) = rie.pwf:pw(1,4):bshow() * (etv) ptn = Partition.new(1, 4):splitn(4) curve = rie.pwf:pw(1,4) rects = rie:rects(ptn, "inf", "sup", "*"):Color("Orange") p = PictList { rects, curve, } = p:bshow() * (etv) rie = Riemann.fromspec("(1,2)c--(3,4)--(5,2)c") ptn = Partition.new(2, 5):splitn(4) curve = rie.pwf:pw(1, 5) curve = rie.pws:topict() rects = rie:rects(ptn, "inf", "sup", "*"):Color("Orange") p = PictList { rects, curve, } = p:bshow() * (etv) * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Piecewise1.lua" Pict2e.bounds = PictBounds.new(v(0,0), v(8,5)) rie = Riemann.fromspec("(0,3)--(2,5)--(6,1)--(8,3)"):setab(1, 7) p = PictList { rie:areasup(3):color("yellow"), rie:areasup(12):color("blue"), rie:area (3):Color("Orange"), rie:areainf(3):Color("Red"), rie:lineify(0, 8), } = p = p:bshow() * (etv) * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Piecewise1.lua" Pict2e.bounds = PictBounds.new(v(0,0), v(11,7)) rie = Riemann.fromspec("(0,3)--(3,6)--(8,1)--(11,4)"):setab(2, 10) ColorUpperA = "red!20!white" ColorUpperB = "Gold1!20!white" ColorUpperC = "Green1!20!white" ColorUpperD = "Blue1!20!white" ColorLowerA = "red!80!white" ColorLowerB = "Gold1!80!white" ColorLowerC = "Green1!80!white" ColorLowerD = "Blue1!80!white" ColorRealInt = "Purple0!90!white" UpperA = rie:areasup( 2):color(ColorUpperA) UpperB = rie:areasup( 4):color(ColorUpperB) UpperC = rie:areasup( 8):color(ColorUpperC) UpperD = rie:areasup(16):color(ColorUpperD) LowerD = rie:areainf(16):color(ColorLowerD) LowerC = rie:areainf( 8):color(ColorLowerC) LowerB = rie:areainf( 4):color(ColorLowerB) LowerA = rie:areainf( 2):color(ColorLowerA) RealInt = rie:area ():color(ColorRealInt) p = PictList { UpperA, UpperB, UpperC, UpperD, RealInt, LowerD, LowerC, LowerB, LowerA, rie:lineify(0, 11), } = p = p:bshow() * (etv) * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Piecewise1.lua" para = function (x) return 4*x - x^2 end vex = function (str) return Code.ve("x => "..str) end rievex = function (str) return Riemann.fromf(vex(str), seq(0, 4, 0.125)) end rievexa = function (str, a, b) local rie = rievex(str) return PictList { rie.pwf:areaify(a, b):Color("Orange"), rie:lineify(0, 4), } end = vex("para(x)")(2) = vex("para(x)/2")(2) p = rievexa("para(x)/2", 3, 4) = p:bshow() * (etv) --]] -- «Riemann-tests-sc» (to ".Riemann-tests-sc") --[[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Piecewise1.lua" -- Semicircle: scxs = {} for _,theta in ipairs(seqn(math.pi, 0, 32)) do table.insert(scxs, math.cos(theta)) end f = function (x) return math.sqrt(1 - x^2) end rie = Riemann.fromf(f, scxs) ptn = Partition.new(-1, 1):splitn(8) curve = rie.pwf:pw(-1, 1) rects = rie:rects(ptn, "inf", "sup", "*"):Color("Orange") p = PictList { rects, curve, } -- = p:bshow() -- (etv) p2 = p:setbounds(v(-2,0), v(2,2)):pgat("pgat"):preunitlength("40pt"):dd() = Show.try(p2:tostringp()) * (etv) --]] -- _____ _____ ____ _ -- |_ _| ___/ ___/ | -- | | | |_ | | | | -- | | | _|| |___| | -- |_| |_| \____|_| -- -- «TFC1» (to ".TFC1") TFC1 = Class { type = "TFC1", frompwf = function (pwf) return TFC1 {pwf=pwf, f=pwf.f} end, fromf = function (f, ...) return TFC1.frompwf(PwFunction.from(f, ...)) end, fromspec = function (spec) local pws = PwSpec.from(spec) local pwf = pws:topwfunction() return TFC1 {pws=pws, pwf=pwf, f=pwf.f} end, __index = { setxts = function (tfc1, x0, x1, x3, t1, scale) tfc1.x0 = x0 tfc1.x1 = x1 tfc1.x3 = x3 tfc1.t1 = t1 tfc1.scale = scale return tfc1 end, ttox = function (tfc1, t2) return (t2 - tfc1.t1)/tfc1.scale + tfc1.x1 end, xtot = function (tfc1, x2) return (x2 - tfc1.x1)*tfc1.scale + tfc1.t1 end, setpwg = function (tfc1) local g = function (t2) return tfc1.f(tfc1:ttox(t2)) end local pwg = PwFunction.from(g) for x in tfc1.pwf.points:gen() do pwg:addpoint(tfc1:xtot(x)) end tfc1.g = g tfc1.pwg = pwg return tfc1 end, areaify_f = function (tfc1) return tfc1.pwf:areaify(tfc1.x1, tfc1.x1 + 1/tfc1.scale) end, areaify_g = function (tfc1) return tfc1.pwg:areaify(tfc1.t1, tfc1.t1 + 1 ) end, lineify_f = function (tfc1) return tfc1.pwf:lineify(tfc1.x0, tfc1.x3) end, lineify_g = function (tfc1) return tfc1.pwg:lineify(tfc1.t1, tfc1.t1 + 1) end, -- areaify_f = function (tfc1) -- corrected version local a,b = tfc1.x1, tfc1.x1 + 1/tfc1.scale return tfc1.pwf:areaify(min(a, b), max(a, b)) end, }, } -- «TFC1-tests» (to ".TFC1-tests") -- (c2m212tfc1p 5 "exemplo-1") -- (c2m212tfc1a "exemplo-1") --[[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Piecewise1.lua" f = function (x) if x < 2 then return x^2 else return 2 end end f = function (x) return 4*x - x^2 end tfc1 = TFC1.fromf(f, 0.9, 1, 1.1, 1.2) tfc1:setxts(0,1,4, 5, 2) tfc1:setxts(0,1,4, 5, 2):setpwg() PPPV(tfc1) = tfc1.pwf.points = tfc1.pwf.points:ksc() = tfc1.f(0.9) = tfc1.g(4.8) Pict2e.bounds = PictBounds.new(v(0,0), v(7,5)) = tfc1.pwf:areaify(0, 4) f = function (x) return 4*x - x^2 end tfc1 = TFC1.fromf(f, seqn(0, 4, 16)) scale = 2 scale = 4 tfc1:setxts(0,1,4, 5, scale):setpwg() PPPV(tfc1.pwf) PPPV(tfc1.pwg) p = PictList { tfc1:areaify_f():Color("Orange"), tfc1:areaify_g():Color("Orange"), tfc1:lineify_f(), tfc1:lineify_g(), } = p = p:bshow() * (etv) * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Piecewise1.lua" Pict2e.bounds = PictBounds.new(v(0,0), v(8,5)) spec = "(0,2)--(1,1)--(2,3)--(3,4)--(4,3)" spec = "(0,2)--(1,0)--(2,1)o (2,2)c (2,3)o--(3,4)--(4,3)" tfc1 = TFC1.fromspec(spec) tfc1:setxts(0,2,4, 5, 1/2) tfc1:setxts(0,2,4, 5, -1/2) p = PictList { tfc1:areaify_f():Color("Orange"), tfc1.pws:topict(), } = p = p:bshow() * (etv) --]] -- __ ___ _ -- \ \/ / |_ _____ ___ _| |_ ___ _ _ -- \ /| __/ _ \ \/ / | | | __/ _ \| | | | -- / \| || (_) > <| |_| | || (_) | |_| | -- /_/\_\\__\___/_/\_\\__, |\__\___/ \__, | -- |___/ |___/ -- -- «Xtoxytoy» (to ".Xtoxytoy") -- Draw figures of the form (x,0)c--(x,y)c--(0,y)c, -- where y=f(x). -- Xtoxytoy = Class { type = "Xtoxytoy", from = function (f, xs) local vlines = PictList {} local hlines = PictList {} local xdots = PictList {} local xydots = PictList {} local ydots = PictList {} for _,x in ipairs(xs) do local y = f(x) vlines:addline(v(x,0), v(x,y)) hlines:addline(v(x,y), v(0,y)) xdots :addcloseddotat(v(x,0)) xydots:addcloseddotat(v(x,y)) ydots :addcloseddotat(v(0,y)) end return Xtoxytoy {vlines=vlines, hlines=hlines, xdots=xdots, xydots=xydots, ydots=ydots} end, __index = { topict = function (xt, options) local p = PradList {} if options:match("v") then p:addobj(xt.vlines) end if options:match("h") then p:addobj(xt.hlines) end if options:match("x") then p:addobj(xt.xdots) end if options:match("p") then p:addobj(xt.xydots) end if options:match("y") then p:addobj(xt.ydots) end return p end, }, } -- «Xtoxytoy-test1» (to ".Xtoxytoy-test1") --[[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Piecewise1.lua" Pict2e.bounds = PictBounds.new(v(0,0), v(8,6)) spec = "(0,1)--(5,6)--(7,4)" pws = PwSpec.from(spec) = pws:topict() f = pws:fun() xtos = Xtoxytoy.from(f, {1, 2}) = xtos:topict("hvxpy") = xtos:topict("v") p = PictList { pws:topict(), xtos:topict("v") } = p = p:bshow("pgat") * (etv) --]] -- «Xtoxytoy-test2» (to ".Xtoxytoy-test2") --[[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Piecewise1.lua" Pict2e.bounds = PictBounds.new(v(0,0), v(23,9)) spec = "(0,1)--(5,6)--(7,4)--(11,8)--(15,4)--(17,6)--(23,0)" xs = { 1,3, 6, 9, 11, 13, 16,19, 21 } labely = -1 pws = PwSpec.from(spec) xtos = Xtoxytoy.from(pws:fun(), xs) vlines = xtos:topict("v") curve = pws:topict() labels = PictList {} for i,x in ipairs(xs) do labels:addputstrat(v(x,labely), "\\cell{x_"..(i-1).."}") end p = PictList { vlines, curve:prethickness("2pt"), labels } = p = p:bshow("pA") * (etv) --]] -- «Xtoxytoy-test3» (to ".Xtoxytoy-test3") -- (find-LATEX "2022-1-C2-somas-3.tex" "imagens-figuras") --[==[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Piecewise1.lua" Pict2e.bounds = PictBounds.new(v(0,0), v(8,4)) Show.preamble = [[ \unitlength=20pt ]] cthick = "2pt" -- curve dthick = "0.25pt" -- dots sthick = "4pt" -- segments -- Curve: cspec = "(0,2)--(2,4)--(6,0)--(8,2)" cpws = PwSpec.from(cspec) curve = cpws:topict():prethickness(cthick) p = PictList { curve } = p:bshow() * (etv) -- Dots: dotsn = function (nsubsegs) local xs = seqn(1, 4, nsubsegs) local dots0 = Xtoxytoy.from(cpws:fun(), xs) local dots = dots0:topict("vhxpy"):prethickness(dthick):Color("Red") return dots end = dotsn(6) = dotsn(12) p = PictList { curve, dotsn(6) } p = PictList { curve, dotsn(12) } = p:bshow() * (etv) -- Segments: sspec = "(1,0)c--(2,0)--(4,0)c" .. " (1,3)c--(2,4)--(4,2)c" .. " (0,2)c--(0,4)c" spws = PwSpec.from(sspec) segs = spws:topict():prethickness(sthick):Color("Orange") p = PictList { curve, segs } = p:bshow() * (etv) --]==] -- ____ _ __ __ -- / ___| |__ __ _ _ __ __ _ __\ \ / /_ _ _ __ -- | | | '_ \ / _` | '_ \ / _` |/ _ \ \ / / _` | '__| -- | |___| | | | (_| | | | | (_| | __/\ V / (_| | | -- \____|_| |_|\__,_|_| |_|\__, |\___| \_/ \__,_|_| -- |___/ -- -- Draw figures to explain changes of variables. -- (c2m221atisp 12 "substituicao-figura") -- (c2m221atisa "substituicao-figura") -- «ChangeVar» (to ".ChangeVar") ChangeVar = Class { type = "ChangeVar", __index = { setxs = function (cv, xmin, xmax, xs) local xtou = function (x) return cv:xtou(x) end local umin,umax = xtou(xmin), xtou(xmax) local us = map(xtou, xs) cv.xmin, cv.xmax, cv.xs = xmin, xmax, xs cv.umin, cv.umax, cv.us = umin, umax, us return cv end, setus = function (cv, umin, umax, us) local utox = function (u) return cv:utox(u) end local xmin,xmax = utox(umin), utox(umax) local xs = map(utox, us) cv.xmin, cv.xmax, cv.xs = xmin, xmax, xs cv.umin, cv.umax, cv.us = umin, umax, us return cv end, setpwfs = function (cv, n) local fx = function (x) return cv:fx(x) end local fu = function (u) return cv:fu(u) end local xs = seqn(cv.xmin, cv.xmax, n or 64) local us = seqn(cv.umin, cv.umax, n or 64) local pwfx = PwFunction.from(fx, xs) local pwfu = PwFunction.from(fu, us) cv.pwfx = pwfx cv.pwfu = pwfu return cv end, setcolors = function (cv, colors) cv.colors = split(colors or "red orange yellow") return cv end, -- curvex = function (cv) return cv.pwfx:lineify(cv.xmin, cv.xmax) end, curveu = function (cv) return cv.pwfu:lineify(cv.umin, cv.umax) end, areax = function (cv, x0, x1) return cv.pwfx:areaify(x0, x1) end, areau = function (cv, u0, u1) return cv.pwfu:areaify(u0, u1) end, color = function (cv, i) return cv.colors[i] end, subareax = function (cv, i) return cv:areax(cv.xs[i], cv.xs[i+1]):color(cv:color(i)) end, subareau = function (cv, i) return cv:areau(cv.us[i], cv.us[i+1]):color(cv:color(i)) end, areasx = function (cv) local p = PictList {} for i=1,#cv.colors do table.insert(p, cv:subareax(i)) end return p end, areasu = function (cv) local p = PictList {} for i=1,#cv.colors do table.insert(p, cv:subareau(i)) end return p end, -- labelat = function (cv, xy, str) return pformat("\\put%s{\\cell{%s}}", xy, str) end, xlabels = function (cv, y) local p = PictList {} for i=1,#cv.xs do table.insert(p, cv:labelat(v(cv.xs[i], y), "x_{"..(i-1).."}")) end return p end, ulabels = function (cv, y) local p = PictList {} for i=1,#cv.us do table.insert(p, cv:labelat(v(cv.us[i], y), "u_{"..(i-1).."}")) end return p end, -- rect = function (cv, a, b, y) return PictList({}):addregion0(v(a,0), v(a,y), v(b,y), v(b,0)) end, }, } -- «ChangeVar-test1» (to ".ChangeVar-test1") -- Supersedes: (to "PwFunction-intfig") -- See: (c2m221atisp 12 "substituicao-figura") -- (c2m221atisa "substituicao-figura") --[==[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Piecewise1.lua" pi, sqrt, sin, cos = math.pi, math.sqrt, math.sin, math.cos xtou = function (x) return x^2 end ve = Code.ve cv = ChangeVar { xtou = ve " cv,x => x^2 ", fx = ve " cv,x => sin(x^2) * 2*x ", fu = ve " cv,u => sin( u ) ", utox = ve " cv,u => sqrt(u) ", } cv:setus(0, pi, {0, 1, 2, 3}) PPPV(cv) cv:setpwfs() cv:setcolors() PPPV(cv) = cv:subareax(1) = cv:areasx() = cv:curvex() = cv:xlabels(-0.5) = cv:rect(1, 1.5, 0.5):color("blue") = cv:rect(cv.xs[2], cv.xs[3], cv:fx(cv.xs[2])):color("blue") Pict2e.bounds = PictBounds.new(v(0,0), v(4,3)) ppx = PictList { cv:areasx(), cv:curvex(), cv:rect(cv.xs[2], cv.xs[3], cv:fx(cv.xs[2])):color("blue"), cv:xlabels(-0.35), } ppu = PictList { cv:areasu(), cv:curveu(), cv:ulabels(-0.35) } pp2 = PictList { ppx:pgat("pgatc"), "\\qquad", ppu:pgat("pgatc"), } = Show.try(pp2:preunitlength("50pt"):scalebox("0.7"):d():tostringp()) * (etv) = pp2:bshow() = ppu:bshow() * (etv) maxu = pi maxx = sqrt(maxu) --]==] -- Local Variables: -- coding: utf-8-unix -- End: