\documentclass[tikz,border=1cm]{standalone}
\usepackage{luacode}
\begin{luacode*}
-- Compute intersections of y=exp(x) with y=m*x+b on [xmin,xmax]
-- Export x-roots into TeX macro \roots (empty if none).
function lineExpIntersections(m,b,xmin,xmax)
local function f(x) return math.exp(x) - (m*x + b) end
local function bisect(L,R, tol, maxit)
tol = tol or 1e-6
maxit = maxit or 60
local fL, fR = f(L), f(R)
if fL*fR > 0 then return nil end
for _=1,maxit do
local M = 0.5*(L+R)
local fM = f(M)
if (R-L) < tol then return M end
if fL*fM < 0 then
R, fR = M, fM
else
L, fL = M, fM
end
end
return 0.5*(L+R)
end
local roots = {}
if m < 0 then
-- strictly increasing => at most one root; find it if bracketed
local r = bisect(xmin, xmax)
if r then roots[#roots+1] = r end
elseif m == 0 then
-- exp(x)=b
if b > 0 then
local r = math.log(b)
if r >= xmin and r <= xmax then roots[#roots+1] = r end
end
else
-- m>0: 0/1/2 roots; minimum at x0=log(m)
local x0 = math.log(m)
local fmin = m - (m*math.log(m) + b) -- f(x0)
if fmin == 0 then
if x0 >= xmin and x0 <= xmax then roots[#roots+1] = x0 end
elseif fmin < 0 then
-- two roots globally; try to bracket each inside [xmin,xmax]
local L1, R1 = xmin, math.min(x0, xmax)
local L2, R2 = math.max(x0, xmin), xmax
local r1 = bisect(L1, R1)
local r2 = bisect(L2, R2)
if r1 then roots[#roots+1] = r1 end
if r2 then roots[#roots+1] = r2 end
end
end
local out = {}
for i=1,#roots do out[i] = string.format("%.12f", roots[i]) end
tex.sprint("\\def\\roots{" .. table.concat(out, ",") .. "}")
end
\end{luacode*}
% TeX wrapper: defines \roots
\newcommand{\LineExpIntersections}[4]{%
\directlua{lineExpIntersections(#1,#2,#3,#4)}%
}
\begin{document}
\begin{tikzpicture}
\draw[->] (-2,0) -- (2,0);
\draw[->] (0,-2) -- (0,{exp(2)});
\draw[domain=-2:2,samples=200] plot (\x,{exp(\x)});
\def\xmin{-2}
\def\xmax{2}
% 1) y = x + 1.5 (two intersections)
\draw[domain=\xmin:\xmax,samples=2] plot (\x,{1*\x+1.5});
\LineExpIntersections{1}{1.5}{\xmin}{\xmax}
\foreach \r in \roots { \fill[red] (\r,{exp(\r)}) circle (1.2pt); }
% 2) y = x + 1 (one intersection)
\draw[domain=\xmin:\xmax,samples=2] plot (\x,{1*\x+1});
\LineExpIntersections{1}{1}{\xmin}{\xmax}
\foreach \r in \roots { \fill[green] (\r,{exp(\r)}) circle (1.2pt); }
% 3) y = -x + 4.5 (one intersection)
\draw[domain=\xmin:\xmax,samples=2] plot (\x,{-1*\x+4.5});
\LineExpIntersections{-1}{4.5}{\xmin}{\xmax}
\foreach \r in \roots { \fill[blue] (\r,{exp(\r)}) circle (1.2pt); }
% 4) y = x (zero intersections)
\draw[domain=\xmin:\xmax,samples=2] plot (\x,{1*\x});
\LineExpIntersections{1}{0}{\xmin}{\xmax}
\foreach \r in \roots { \fill (\r,{exp(\r)}) circle (1.2pt); }
% 5) y = x + 4 (zero intersections)
\draw[domain=\xmin:\xmax,samples=2] plot (\x,{1*\x+4});
\LineExpIntersections{1}{4}{\xmin}{\xmax}
\foreach \r in \roots { \fill[orange] (\r,{exp(\r)}) circle (1.2pt); }
% 6) y = x + 5 (no intersections on [xmin,xmax]” или “roots outside the interval)
\def\txmax{1.5}
\draw[domain=\xmin:\txmax,samples=2] plot (\x,{1*\x+5});
\LineExpIntersections{1}{5}{\xmin}{\txmax}
\foreach \r in \roots { \fill[orange] (\r,{exp(\r)}) circle (1.2pt); }
\end{tikzpicture}
\end{document}
-- Compute intersections of y=exp(x) with y=m*x+b on [xmin,xmax]
-- Export x-roots into TeX macro \roots (empty if none).
function lineExpIntersections(m,b,xmin,xmax)
local function f(x) return math.exp(x) - (m*x + b) end
local function bisect(L,R, tol, maxit)
tol = tol or 1e-6
maxit = maxit or 60
local fL, fR = f(L), f(R)
if fL*fR > 0 then return nil end
for _=1,maxit do
local M = 0.5*(L+R)
local fM = f(M)
if (R-L) < tol then return M end
if fL*fM < 0 then
R, fR = M, fM
else
L, fL = M, fM
end
end
return 0.5*(L+R)
end
local roots = {}
if m < 0 then
-- strictly increasing => at most one root; find it if bracketed
local r = bisect(xmin, xmax)
if r then roots[#roots+1] = r end
elseif m == 0 then
-- exp(x)=b
if b > 0 then
local r = math.log(b)
if r >= xmin and r <= xmax then roots[#roots+1] = r end
end
else
-- m>0: 0/1/2 roots; minimum at x0=log(m)
local x0 = math.log(m)
local fmin = m - (m*math.log(m) + b) -- f(x0)
if fmin == 0 then
if x0 >= xmin and x0 <= xmax then roots[#roots+1] = x0 end
elseif fmin < 0 then
-- two roots globally; try to bracket each inside [xmin,xmax]
local L1, R1 = xmin, math.min(x0, xmax)
local L2, R2 = math.max(x0, xmin), xmax
local r1 = bisect(L1, R1)
local r2 = bisect(L2, R2)
if r1 then roots[#roots+1] = r1 end
if r2 then roots[#roots+1] = r2 end
end
end
local out = {}
for i=1,#roots do out[i] = string.format("%.12f", roots[i]) end
tex.sprint("\\def\\roots{" .. table.concat(out, ",") .. "}")
end
\end{luacode*}
% TeX wrapper: defines \roots
\newcommand{\LineExpIntersections}[4]{%
\directlua{lineExpIntersections(#1,#2,#3,#4)}%
}
\begin{document}
\begin{tikzpicture}
\draw[->] (-2,0) -- (2,0);
\draw[->] (0,-2) -- (0,{exp(2)});
\draw[domain=-2:2,samples=200] plot (\x,{exp(\x)});
\def\xmin{-2}
\def\xmax{2}
% 1) y = x + 1.5 (two intersections)
\draw[domain=\xmin:\xmax,samples=2] plot (\x,{1*\x+1.5});
\LineExpIntersections{1}{1.5}{\xmin}{\xmax}
\foreach \r in \roots { \fill[red] (\r,{exp(\r)}) circle (1.2pt); }
% 2) y = x + 1 (one intersection)
\draw[domain=\xmin:\xmax,samples=2] plot (\x,{1*\x+1});
\LineExpIntersections{1}{1}{\xmin}{\xmax}
\foreach \r in \roots { \fill[green] (\r,{exp(\r)}) circle (1.2pt); }
% 3) y = -x + 4.5 (one intersection)
\draw[domain=\xmin:\xmax,samples=2] plot (\x,{-1*\x+4.5});
\LineExpIntersections{-1}{4.5}{\xmin}{\xmax}
\foreach \r in \roots { \fill[blue] (\r,{exp(\r)}) circle (1.2pt); }
% 4) y = x (zero intersections)
\draw[domain=\xmin:\xmax,samples=2] plot (\x,{1*\x});
\LineExpIntersections{1}{0}{\xmin}{\xmax}
\foreach \r in \roots { \fill (\r,{exp(\r)}) circle (1.2pt); }
% 5) y = x + 4 (zero intersections)
\draw[domain=\xmin:\xmax,samples=2] plot (\x,{1*\x+4});
\LineExpIntersections{1}{4}{\xmin}{\xmax}
\foreach \r in \roots { \fill[orange] (\r,{exp(\r)}) circle (1.2pt); }
% 6) y = x + 5 (no intersections on [xmin,xmax]” или “roots outside the interval)
\def\txmax{1.5}
\draw[domain=\xmin:\txmax,samples=2] plot (\x,{1*\x+5});
\LineExpIntersections{1}{5}{\xmin}{\txmax}
\foreach \r in \roots { \fill[orange] (\r,{exp(\r)}) circle (1.2pt); }
\end{tikzpicture}
\end{document}
\documentclass[tikz,border=1cm]{standalone}
\usepackage{luacode}
\begin{luacode*}
-- Compute intersections of y=exp(x) with y=m*x+b on [xmin,xmax]
-- method = "bisection" or "newton"
-- Export x-roots into TeX macro \roots (empty if none).
function lineExpIntersections(m,b,xmin,xmax, method)
method = method or "bisection"
local function f(x) return math.exp(x) - (m*x + b) end
local function df(x) return math.exp(x) - m end
local function bisect(L,R, tol, maxit)
tol = tol or 1e-6
maxit = maxit or 60
local fL, fR = f(L), f(R)
if fL*fR > 0 then return nil end
for _=1,maxit do
local M = 0.5*(L+R)
local fM = f(M)
if (R-L) < tol then return M end
if fL*fM < 0 then
R, fR = M, fM
else
L, fL = M, fM
end
end
return 0.5*(L+R)
end
-- Plain Newton on [L,R], starting from an endpoint (no fallback).
local function newton(L,R, tol, maxit)
tol = tol or 1e-6
maxit = maxit or 30
local fL, fR = f(L), f(R)
if fL*fR > 0 then return nil end
-- start from the endpoint with smaller |f|
local x = (math.abs(fL) <= math.abs(fR)) and L or R
-- if derivative is too small at chosen endpoint, try the other one
if math.abs(df(x)) < 1e-15 then
x = (x == L) and R or L
if math.abs(df(x)) < 1e-15 then return nil end
end
for _=1,maxit do
local fx = f(x)
if math.abs(fx) < tol then return x end
local dfx = df(x)
if math.abs(dfx) < 1e-15 then return nil end
local xnew = x - fx/dfx
if xnew <= L or xnew >= R then return nil end
x = xnew
end
return nil
end
local function solve_on_interval(L,R)
if method == "newton" then
return newton(L,R, 1e-6, 30)
else
return bisect(L,R, 1e-6, 60)
end
end
local roots = {}
if m < 0 then
local r = solve_on_interval(xmin, xmax)
if r then roots[#roots+1] = r end
elseif m == 0 then
if b > 0 then
local r = math.log(b)
if r >= xmin and r <= xmax then roots[#roots+1] = r end
end
else
local x0 = math.log(m)
local fmin = m - (m*math.log(m) + b) -- f(x0)
if fmin == 0 then
if x0 >= xmin and x0 <= xmax then roots[#roots+1] = x0 end
elseif fmin < 0 then
local L1, R1 = xmin, math.min(x0, xmax)
local L2, R2 = math.max(x0, xmin), xmax
local r1 = solve_on_interval(L1, R1)
local r2 = solve_on_interval(L2, R2)
if r1 then roots[#roots+1] = r1 end
if r2 then roots[#roots+1] = r2 end
end
end
local out = {}
for i=1,#roots do out[i] = string.format("%.12f", roots[i]) end
tex.sprint("\\def\\roots{" .. table.concat(out, ",") .. "}")
end
\end{luacode*}
% TeX wrapper: #5 is method: bisection/newton
\newcommand{\LineExpIntersections}[5]{%
\directlua{lineExpIntersections(#1,#2,#3,#4,"#5")}%
}
\begin{document}
\begin{tikzpicture}
\draw[->] (-2,0) -- (2,0);
\draw[->] (0,-2) -- (0,{exp(2)});
\draw[domain=-2:2,samples=200] plot (\x,{exp(\x)});
\def\xmin{-2}
\def\xmax{2}
% Choose one:
%\def\method{bisection}
\def\method{newton}
% 1) y = x + 1.5
\draw[domain=\xmin:\xmax,samples=2] plot (\x,{1*\x+1.5});
\LineExpIntersections{1}{1.5}{\xmin}{\xmax}{\method}
\foreach \r in \roots { \fill[red] (\r,{exp(\r)}) circle (1.2pt); }
% 2) y = x + 1
\draw[domain=\xmin:\xmax,samples=2] plot (\x,{1*\x+1});
\LineExpIntersections{1}{1}{\xmin}{\xmax}{\method}
\foreach \r in \roots { \fill[green] (\r,{exp(\r)}) circle (1.2pt); }
% 3) y = -x + 4.5
\draw[domain=\xmin:\xmax,samples=2] plot (\x,{-1*\x+4.5});
\LineExpIntersections{-1}{4.5}{\xmin}{\xmax}{\method}
\foreach \r in \roots { \fill[blue] (\r,{exp(\r)}) circle (1.2pt); }
% 4) y = x
\draw[domain=\xmin:\xmax,samples=2] plot (\x,{1*\x});
\LineExpIntersections{1}{0}{\xmin}{\xmax}{\method}
\foreach \r in \roots { \fill (\r,{exp(\r)}) circle (1.2pt); }
% 5) y = x + 4 (root outside [-2,2])
\draw[domain=\xmin:\xmax,samples=2] plot (\x,{1*\x+4});
\LineExpIntersections{1}{4}{\xmin}{\xmax}{\method}
\foreach \r in \roots { \fill[orange] (\r,{exp(\r)}) circle (1.2pt); }
% 6) y = x + 5 (no intersections on [-2,1.5])
\def\txmax{1.5}
\draw[domain=\xmin:\txmax,samples=2] plot (\x,{1*\x+5});
\LineExpIntersections{1}{5}{\xmin}{\txmax}{\method}
\foreach \r in \roots { \fill[yellow] (\r,{exp(\r)}) circle (1.2pt); }
\end{tikzpicture}
\end{document}
-- Compute intersections of y=exp(x) with y=m*x+b on [xmin,xmax]
-- method = "bisection" or "newton"
-- Export x-roots into TeX macro \roots (empty if none).
function lineExpIntersections(m,b,xmin,xmax, method)
method = method or "bisection"
local function f(x) return math.exp(x) - (m*x + b) end
local function df(x) return math.exp(x) - m end
local function bisect(L,R, tol, maxit)
tol = tol or 1e-6
maxit = maxit or 60
local fL, fR = f(L), f(R)
if fL*fR > 0 then return nil end
for _=1,maxit do
local M = 0.5*(L+R)
local fM = f(M)
if (R-L) < tol then return M end
if fL*fM < 0 then
R, fR = M, fM
else
L, fL = M, fM
end
end
return 0.5*(L+R)
end
-- Plain Newton on [L,R], starting from an endpoint (no fallback).
local function newton(L,R, tol, maxit)
tol = tol or 1e-6
maxit = maxit or 30
local fL, fR = f(L), f(R)
if fL*fR > 0 then return nil end
-- start from the endpoint with smaller |f|
local x = (math.abs(fL) <= math.abs(fR)) and L or R
-- if derivative is too small at chosen endpoint, try the other one
if math.abs(df(x)) < 1e-15 then
x = (x == L) and R or L
if math.abs(df(x)) < 1e-15 then return nil end
end
for _=1,maxit do
local fx = f(x)
if math.abs(fx) < tol then return x end
local dfx = df(x)
if math.abs(dfx) < 1e-15 then return nil end
local xnew = x - fx/dfx
if xnew <= L or xnew >= R then return nil end
x = xnew
end
return nil
end
local function solve_on_interval(L,R)
if method == "newton" then
return newton(L,R, 1e-6, 30)
else
return bisect(L,R, 1e-6, 60)
end
end
local roots = {}
if m < 0 then
local r = solve_on_interval(xmin, xmax)
if r then roots[#roots+1] = r end
elseif m == 0 then
if b > 0 then
local r = math.log(b)
if r >= xmin and r <= xmax then roots[#roots+1] = r end
end
else
local x0 = math.log(m)
local fmin = m - (m*math.log(m) + b) -- f(x0)
if fmin == 0 then
if x0 >= xmin and x0 <= xmax then roots[#roots+1] = x0 end
elseif fmin < 0 then
local L1, R1 = xmin, math.min(x0, xmax)
local L2, R2 = math.max(x0, xmin), xmax
local r1 = solve_on_interval(L1, R1)
local r2 = solve_on_interval(L2, R2)
if r1 then roots[#roots+1] = r1 end
if r2 then roots[#roots+1] = r2 end
end
end
local out = {}
for i=1,#roots do out[i] = string.format("%.12f", roots[i]) end
tex.sprint("\\def\\roots{" .. table.concat(out, ",") .. "}")
end
\end{luacode*}
% TeX wrapper: #5 is method: bisection/newton
\newcommand{\LineExpIntersections}[5]{%
\directlua{lineExpIntersections(#1,#2,#3,#4,"#5")}%
}
\begin{document}
\begin{tikzpicture}
\draw[->] (-2,0) -- (2,0);
\draw[->] (0,-2) -- (0,{exp(2)});
\draw[domain=-2:2,samples=200] plot (\x,{exp(\x)});
\def\xmin{-2}
\def\xmax{2}
% Choose one:
%\def\method{bisection}
\def\method{newton}
% 1) y = x + 1.5
\draw[domain=\xmin:\xmax,samples=2] plot (\x,{1*\x+1.5});
\LineExpIntersections{1}{1.5}{\xmin}{\xmax}{\method}
\foreach \r in \roots { \fill[red] (\r,{exp(\r)}) circle (1.2pt); }
% 2) y = x + 1
\draw[domain=\xmin:\xmax,samples=2] plot (\x,{1*\x+1});
\LineExpIntersections{1}{1}{\xmin}{\xmax}{\method}
\foreach \r in \roots { \fill[green] (\r,{exp(\r)}) circle (1.2pt); }
% 3) y = -x + 4.5
\draw[domain=\xmin:\xmax,samples=2] plot (\x,{-1*\x+4.5});
\LineExpIntersections{-1}{4.5}{\xmin}{\xmax}{\method}
\foreach \r in \roots { \fill[blue] (\r,{exp(\r)}) circle (1.2pt); }
% 4) y = x
\draw[domain=\xmin:\xmax,samples=2] plot (\x,{1*\x});
\LineExpIntersections{1}{0}{\xmin}{\xmax}{\method}
\foreach \r in \roots { \fill (\r,{exp(\r)}) circle (1.2pt); }
% 5) y = x + 4 (root outside [-2,2])
\draw[domain=\xmin:\xmax,samples=2] plot (\x,{1*\x+4});
\LineExpIntersections{1}{4}{\xmin}{\xmax}{\method}
\foreach \r in \roots { \fill[orange] (\r,{exp(\r)}) circle (1.2pt); }
% 6) y = x + 5 (no intersections on [-2,1.5])
\def\txmax{1.5}
\draw[domain=\xmin:\txmax,samples=2] plot (\x,{1*\x+5});
\LineExpIntersections{1}{5}{\xmin}{\txmax}{\method}
\foreach \r in \roots { \fill[yellow] (\r,{exp(\r)}) circle (1.2pt); }
\end{tikzpicture}
\end{document}