\documentclass{article} \usepackage{luacas} \usepackage{amsmath} \usepackage{amssymb} \usepackage[margin=1in]{geometry} \usepackage[shortlabels]{enumitem} \usepackage{pgfplots} \pgfplotsset{compat=1.18} \usetikzlibrary{positioning,calc} \usepackage{forest} \usepackage{minted} \usemintedstyle{pastie} \usepackage[hidelinks]{hyperref} \usepackage{parskip} \usepackage{multicol} \usepackage[most]{tcolorbox} \tcbuselibrary{xparse} \usepackage{microtype} \definecolor{rose}{RGB}{128,0,0} \definecolor{roseyellow}{RGB}{222,205,99} \definecolor{roseblue}{RGB}{167,188,214} \definecolor{rosenavy}{RGB}{79,117,139} \definecolor{roseorange}{RGB}{232,119,34} \definecolor{rosegreen}{RGB}{61,68,30} \definecolor{rosewhite}{RGB}{223,209,167} \definecolor{rosebrown}{RGB}{108,87,27} \definecolor{rosegray}{RGB}{84,88,90} \usepackage[ backend=biber, style=numeric, ]{biblatex} \addbibresource{sources.bib} \newtcolorbox{codebox}[1][sidebyside]{ enhanced,skin=bicolor, #1, arc=1pt, colframe=brown, colback=brown!15,colbacklower=white, boxrule=1pt, notitle } \begin{document} \subsection{Tutorial 2: Finding Maxima/Minima} Bob is teaching calculus too, and he wants to give his students many examples of the process of \emph{finding the local max/min of a given function}. But, like Alice, Bob doesn't want to work out a bunch of examples by-hand. Bob decides to try his hand with \texttt{luacas} after having been taught the basics by Alice. Bob decides to stick with polynomials for these examples; if anything because those functions are in the wheel-house of \texttt{luacas}. In particular, Bob decides that the \emph{derivative} of the function he wants to use should be a composition of quadratics. This ought to ensure that the roots of that derivative are expressible in a nice way. Accordingly, Bob declares variables and chooses two quadratic polynomials to compose, say $f$ and $g$, and sets $dh = g \circ f$: \begin{minted}{latex} \begin{CAS} vars('x') f = x^2+2*x-2 g = x^2-1 subs = {[x] = f} dh = substitute(subs,g) \end{CAS} \end{minted} \begin{CAS} vars('x') f = x^2+2*x-2 g = x^2-1 subs = {[x] = f} dh = substitute(subs,g) \end{CAS} Bob wants to compute $h$, the integral of $dh$. Bob could certainly compute this quantity by-hand, but why hardcode that information into the document when \texttt{luacas} can do this for you? So Bob uses the \texttt{int} command and shifts the result (with some malice aforethought): \begin{minted}{latex} \begin{CAS} h = int(dh,x) + 10 \end{CAS} \end{minted} \begin{CAS} h = int(dh,x) + 10 \end{CAS} Bob is curious to know the value of $h$. So he uses \mintinline{latex}{\print{h}} to produce: \begin{codebox} \begin{minted}[fontsize=\small]{latex} \[ \print{h} \] \end{minted} \tcblower \[\print{h} \] \end{codebox} This isn't exactly what Bob had in mind. It occurs to Bob that he may need to simplify the expression $h$, so he tries: \begin{codebox} \begin{minted}[fontsize=\small]{latex} \begin{CAS} h = simplify(int(dh,x)+10) \end{CAS} \[ \print{h} \] \end{minted} \tcblower \begin{CAS} h = simplify(h) \end{CAS} \[\print{h} \] \end{codebox} That's more like it! Now, Bob wants to find the roots to $dh$. Bob uses the \texttt{roots} command to do this: \begin{minted}{latex} \begin{CAS} r = roots(dh) \end{CAS} \end{minted} \begin{CAS} r = roots(dh) \end{CAS} But then Bob wonders to himself, ``How do I actually retrieve the roots of $dh$ from \texttt{luacas}?'' The assignment \mintinline{lua}{r = roots(dh)} stores the roots of the polynomial $dh$ in a table named \texttt{r}: \begin{codebox}[] \begin{minted}[fontsize=\small]{latex} \[ \print{r[1]}, \quad \print{r[2]}, \quad \print{r[3]}, \quad\print{r[4]} \] \end{minted} \tcblower \begin{CAS} r = roots(dh) \end{CAS} \[ \print{r[1]}, \quad \print{r[2]}, \quad \print{r[3]}, \quad \print{r[4]} \] \end{codebox} If Bob truly wants to print the entire list \texttt{r}, Bob can use the \mintinline{latex}{\lprint} (\textbf{l}ist \textbf{print}) command: \begin{codebox}[] \begin{minted}[fontsize=\small]{latex} \[ \left\{ \lprint{r} \right\} \] \end{minted} \tcblower \[ \left\{ \lprint{r} \right\} \] \end{codebox} Splendid! Bob would now like to evaluate the function $h$ at these roots (for these are the local max/min values of $h$). Here's Bob's first thought: \begin{codebox} \begin{minted}[fontsize=\small]{latex} \begin{CAS} v = simplify(substitute({[x]=r[1]},h)) \end{CAS} \[ \print{v} \] \end{minted} \tcblower \begin{CAS} v = simplify(substitute({[x]=r[1]},h)) \end{CAS} \[ \print{v} \] \end{codebox} What the heck?! Bob is (understandably) confused. But here's where Bob learns a valuable lesson\dots \subsubsection{A brief interlude: Lua numbers vs \texttt{luacas Integers}} The \LaTeX{} environment \mintinline{latex}{\begin{CAS}..\end{CAS}} is really a glorified Lua environment. The ``glory'' comes in how the contents of the environment are parsed in a special manner to make interacting with the CAS (mostly) easy. Bob has encountered a situation where that interaction is not as easy as we'd like. For comparison, consider the following: \begin{multicols}{2} Here's some code using the \mintinline{latex}{\begin{CAS}..\end{CAS}}: \begin{codebox}\small \begin{minted}[fontsize=\small]{latex} \begin{CAS} vars('y') a = 1 b = y+a \end{CAS} \[ \print{b} \] \end{minted} \tcblower \begin{CAS} vars('y') a = 1 b = y+a \end{CAS} \[ \print{b} \] \end{codebox} Here's that same code but using \mintinline{latex}{\directlua} instead: \begin{codebox}\small \begin{minted}[fontsize=\small]{latex} \directlua{ vars('y') a = Integer(1) b = y+a } \[ \print{b} \] \end{minted} \tcblower \directlua{ vars('y') a = Integer(1) b = y+a } \[ \print{b} \] \end{codebox} \end{multicols} The essential difference being: \begin{itemize} \item Using \mintinline{latex}{\begin{CAS}..\end{CAS}}, a parser automatically interprets any digit strings as an \texttt{Integer}; this is a special class defined within the bowels of \texttt{luacas}. Ultimately, it allows for us to define things like the addition of an \texttt{Integer} and an \texttt{Expression} (in this case, the result is a new \texttt{Expression}) as well as arbitrary precision arithmetic. \item Using \mintinline{latex}{\directlua}, there is no parsing, so the user (aka Bob) is responsible for telling \texttt{luacas} what to interpret as an \texttt{Integer} versus what to interpret as a normal Lua \texttt{number}. \end{itemize} Generally speaking, we like what the parser in \mintinline{latex}{\begin{CAS}..\end{CAS}} does: it keeps us from having to wrap all integers in \texttt{Integer(..)} (among other things). But the price we pay is that the parser indiscriminately wraps \emph{all} (or rather, most) digit strings in \texttt{Integer(..)}. This causes a problem in the following line in Bob's code: \begin{minted}{lua} v = simplify(substitute({[x]=r[1]},h)) \end{minted} The parser sees \mintinline{lua}{r[1]} and interprets \texttt{1} as \texttt{Integer(1)} -- but \mintinline{lua}{r[Integer(1)]} is \texttt{nil}, so no substitution is performed. The good news is that, excluding the annoyance between \texttt{Integer} and Lua number, interacting with the CAS via \mintinline{latex}{\directlua} is not much different than interacting with it via \mintinline{latex}{\begin{CAS}..\end{CAS}}. \subsubsection*{Back to the tutorial...} After that enlightening interlude, Bob realizes that some care needs to be taken when constructing tables. Here's a solution from within \mintinline{latex}{\begin{CAS}..\end{CAS}}: \begin{codebox}[] \begin{minted}[fontsize=\small]{latex} \begin{CAS} r = ZTable(r) v = ZTable() for i in range(1, 4) do v[i] = simplify(substitute({[x]=r[i]},h)) end \end{CAS} \[ \left\{ \lprint{v} \right\} \] \end{minted} \tcblower \begin{CAS} r = ZTable(r) v = ZTable() for i in range(1, 4) do v[i] = simplify(substitute({[x]=r[i]},h)) end \end{CAS} \[ \left\{ \lprint{v} \right\} \] \end{codebox} The function \mintinline{lua}{ZTable()} sets indices appropriately for use within \mintinline{latex}{\begin{CAS}..\end{CAS}} while the function \mintinline{lua}{range()} protects the bounds of the for-loop. Alternatively, Bob can make tables directly within \mintinline{latex}{\directlua} (or \mintinline{latex}{\luaexec} from the \texttt{luacode} package) using whatever Lua syntax pleases him: \begin{codebox}[] \begin{minted}[fontsize=\small]{latex} \directlua{ v = {} for i=1,4 do table.insert(v,simplify(substitute({[x]=r[i]},h))) end} \[ \left\{ \lprint{v} \right\} \] \end{minted} \tcblower \directlua{ v = {} for i=1,4 do table.insert(v,simplify(substitute({[x]=r[i]},h))) end } \[ \left\{ \lprint{v} \right\} \] \end{codebox} Great! But still; Bob doesn't want to just pretty-print the roots of $dh$ (or the values that $h$ takes at those roots). Bob is determined to plot the results -- he wants to hammer home the point that the roots of $dh$ point to the local extrema of $h$. Luckily, Bob is familiar with some of the fantastic graphics tools in the \LaTeX{} ecosystem, like \texttt{pgfplots} and \texttt{asymptote}. But then Bob begins to wonder, ``How can I yoink results out of \texttt{luacas} so that I may yeet them into something like \texttt{pgfplots}?'' Bob is delighted to find the following commands: \mintinline{latex}{\fetch} and \mintinline{latex}{\store}. Whereas the \mintinline{latex}{\print} command relies on the \texttt{luacas} method \mintinline{lua}{tolatex()}, the commands \mintinline{latex}{\fetch} and \mintinline{latex}{\store} rely on the \texttt{luacas} function \mintinline{lua}{tostring()}. Bob can view the output of \mintinline{lua}{tostring()} using the \mintinline{latex}{\vprint} command ({\bf v}erbatim {\bf print}). For example, \mintinline{latex}{\vprint{h}} produces: \vprint{h} This is more-or-less what Bob wants -- but he doesn't want the verbatim output printed to his document, Bob just wants the contents of \mintinline{lua}{tostring(h)}. Here's where \mintinline{latex}{\fetch} comes in. The command \mintinline{latex}{\fetch{h}} is equivalent to: \begin{minted}{latex} \directlua{ tex.print(tostring(h)) } \end{minted} For comparison, the command \mintinline{latex}{\print{h}} is equivalent to: \begin{minted}{latex} \directlua{ tex.print(h:tolatex()) } \end{minted} For Bob's purposes, \mintinline{latex}{\fetch{h}} is exactly what he needs: \begin{codebox}\small \begin{minted}[breaklines,fontsize=\small]{latex} \begin{tikzpicture}[scale=0.9] \begin{axis}[legend pos = north west] \addplot [domain=-3.5:1.5,samples=100] {\fetch{h}}; \addlegendentry{$f$}; \addplot[densely dashed] [domain=-3.25:1.25,samples=100] {\fetch{dh}}; \addlegendentry{$df/dx$}; \addplot[gray,dashed,thick] [domain=-3.5:1.5] {0}; \end{axis} \end{tikzpicture} \end{minted} \tcblower \begin{tikzpicture}[scale=0.9] \begin{axis}[legend pos = north west] \addplot [domain=-3.5:1.5,samples=100] {\fetch{h}}; \addlegendentry{$f$}; \addplot[densely dashed] [domain=-3.25:1.25,samples=100] {\fetch{dh}}; \addlegendentry{$df/dx$}; \addplot[gray,dashed,thick] [domain=-3.5:1.5] {0}; \end{axis} \end{tikzpicture} \end{codebox} Alternatively, Bob could use \mintinline{latex}{\store}. The \mintinline{latex}{\store} command will \emph{fetch} the contents of its mandatory argument and store it in a macro of the same name. \begin{minted}{latex} \store{h} \store{dh} \end{minted} Now the macros \mintinline{latex}{\h} and \mintinline{latex}{\dh} can be used in place of \mintinline{latex}{\fetch{h}} and \mintinline{latex}{\fetch{dh}}, respectively. An optional argument can be used to store contents in a macro under a different name. This is useful for situations like the following: \begin{minted}{latex} \store{r[1]}[rootone] \end{minted} Now \mintinline{latex}{\rootone} can be used in place of \mintinline{latex}{\fetch{r[1]}}. But Bob wants to fetch all the values stored in \texttt{r} (and \texttt{v}, for that matter). In this case, Bob can use: \begin{minted}{latex} \store{r} \store{v} \end{minted} The command \mintinline{latex}{\store{r}} is equivalent to: \begin{minted}{latex} \def\r{{ \fetch{r[1]}, \fetch{r[2]}, \fetch{r[3]}, \fetch{r[4]} }} \end{minted} The contents of the \LaTeX{} macro \mintinline{latex}{\r} can be accessed with \mintinline{latex}{\pgfmathsetmacro}. For example: \begin{codebox} \begin{minted}[fontsize=\small,numbersep=6pt,linenos]{latex} \begin{tikzpicture}[scale=0.6] \draw [dashed,latex-latex] (-7,0) -- (4,0); \foreach \k in {0,1,2,3}{ \pgfmathsetmacro\a{\r[\k]} \draw (\a,0) circle (\a); } \foreach \x in {-6,...,3}{ \draw[fill,orange] (\x,0) circle (2pt) node[below] {\footnotesize$\x$}; } \end{tikzpicture} \end{minted} \tcblower \store{r} \begin{center} \begin{tikzpicture}[scale=0.65] \draw [dashed,latex-latex] (-7,0) -- (4,0); \foreach \k in {0,1,2,3}{ \pgfmathsetmacro\a{\r[\k]} \draw (\a,0) circle (\a); } \foreach \x in {-6,...,3}{ \draw[fill,orange] (\x,0) circle (2pt) node[below] {\footnotesize$\x$}; } \end{tikzpicture} \end{center} \end{codebox} Alternatively, Bob could avoid the call to \mintinline{latex}{\pgfmathsetmacro} by replacing lines 5-6 in the above code with the slightly more verbose: \begin{minted}{latex} \draw ({\fetch{r[\k]}},0) circle (\fetch{r[\k]}); \end{minted} Alternatively still, Bob could appeal directly to the \mintinline{lua}{tostring()} function in \texttt{luacas} and iterate over tables like \texttt{r} using Lua itself. This can often be a simpler solution (particularly when working within \mintinline{latex}{\begin{axis}..\end{axis}}), and it is exactly what Bob does in his complete project shared below: \begin{codebox}[frame hidden,breakable] \begin{minted}[breaklines,fontsize=\small]{latex} Consider the function $f(x)$ defined by: \begin{CAS} vars('x') f = x^2+2*x-2 g = x^2-1 subs = {[x] = f} dh = expand(substitute(subs,g)) h = simplify(int(dh,x)+10) \end{CAS} $\displaystyle f(x) = \print{h}$. \begin{multicols}{2} Note that: \[ f'(x) = \print{dh}.\] The roots to $f'(x)=0$ equation are: \begin{CAS} r = roots(dh) \end{CAS} \[ \left\{ \lprint{r} \right\} \] Recall: $f'(x_0)$ measures the slope of the tangent line to $y= (x)$ at $x=x_0$. The values $r$ where $f'(r)=0$ correspond to places where the slope of the tangent line to $y=f(x)$ is horizontal (see the illustration). This gives us a method for identifying locations where the graph $y=f(x)$ attains a peak (local maximum) or a valley (local minimum). \begin{CAS} r = ZTable(r) v = ZTable() for i in range(1, 4) do v[i] = simplify(substitute({[x]=r[i]},h)) end \end{CAS} \columnbreak \store{h}\store{dh} \begin{tikzpicture}[scale=0.95] \begin{axis}[legend pos = north west] \addplot [domain=-3.5:1.5,samples=100] {\h}; \addlegendentry{$f$}; \addplot[densely dashed] [domain=-3.25:1.25,samples=100] {\dh}; \addlegendentry{$df/dx$}; \addplot[gray,dashed,thick] [domain=-3.5:1.5] {0}; \luaexec{for i=1,4 do tex.print("\\draw[fill=purple,purple]", "(axis cs:{",tostring(r[i]),"},0) circle (1.5pt)", "(axis cs:{",tostring(r[i]),"},{",tostring(v[i]),"}) circle (1.5pt)", "(axis cs:{",tostring(r[i]),"},{",tostring(v[i]),"}) edge[dashed] (axis cs:{",tostring(r[i]),"},0);") end} \end{axis} \end{tikzpicture} \end{multicols} \end{minted} \end{codebox} And here is Bob's completed project: \begin{tcolorbox}[colback=rosenavy!10, colframe=rosenavy, arc=1pt, frame hidden] {\bf Tutorial 2:} {\itshape A local max/min diagram for Bob}. \vskip 0.2cm Consider the function $f(x)$ defined by: \begin{CAS} vars('x') f = x^2+2*x-2 g = x^2-1 subs = {[x] = f} dh = expand(substitute(subs,g)) h = simplify(int(dh,x)+10) \end{CAS} $\displaystyle f(x) = \print{h}$. \begin{multicols}{2} Note that: \[ f'(x) = \print{dh}.\] The roots to $f'(x)=0$ equation are: \begin{CAS} r = roots(dh) \end{CAS} \[ \left\{ \lprint{r} \right\} \] Recall: $f'(x_0)$ measures the slope of the tangent line to $y=f(x)$ at $x=x_0$. The values $r$ where $f'(r)=0$ correspond to places where the slope of the tangent line to $y=f(x)$ is horizontal (see the illustration). This gives us a method for identifying locations where the graph $y=f(x)$ attains a peak (local maximum) or a valley (local minimum). \begin{CAS} r = ZTable(r) v = ZTable() for i in range(1, 4) do v[i] = simplify(substitute({[x]=r[i]},h)) end \end{CAS} \columnbreak \store{h}\store{dh} \begin{tikzpicture}[scale=0.95] \begin{axis}[legend pos = north west] \addplot [domain=-3.5:1.5,samples=100] {\h}; \addlegendentry{$f$}; \addplot[densely dashed] [domain=-3.25:1.25,samples=100] {\dh}; \addlegendentry{$df/dx$}; \addplot[gray,dashed,thick] [domain=-3.5:1.5] {0}; \luaexec{for i=1,4 do tex.print("\\draw[fill=purple,purple]", "(axis cs:{", tostring(r[i]) ,"},0) circle (1.5pt)", "(axis cs:{", tostring(r[i]) ,"},{", tostring(v[i]), "}) circle (1.5pt)", "(axis cs:{", tostring(r[i]) ,"},{", tostring(v[i]), "}) edge[dashed] (axis cs:{", tostring(r[i]) ,"},0);") end} \end{axis} \end{tikzpicture} \end{multicols} \end{tcolorbox} \end{document}