summaryrefslogtreecommitdiff
path: root/macros/luatex/latex/luacas/doc/tutorial/tut2/tut2.tex
blob: a80e2857823b3b2e65b919d2c2a6332f45d97181 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
\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}