diff options
Diffstat (limited to 'macros/luatex/latex/luacas/doc/reference/ref_core/ref_core_classes/ref_core_classes.tex')
-rw-r--r-- | macros/luatex/latex/luacas/doc/reference/ref_core/ref_core_classes/ref_core_classes.tex | 455 |
1 files changed, 455 insertions, 0 deletions
diff --git a/macros/luatex/latex/luacas/doc/reference/ref_core/ref_core_classes/ref_core_classes.tex b/macros/luatex/latex/luacas/doc/reference/ref_core/ref_core_classes/ref_core_classes.tex new file mode 100644 index 0000000000..77e80aa16f --- /dev/null +++ b/macros/luatex/latex/luacas/doc/reference/ref_core/ref_core_classes/ref_core_classes.tex @@ -0,0 +1,455 @@ +\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,documentation} +\usepackage{microtype} +\usepackage{makeidx} +\usepackage{fontawesome5} +\usepackage{marginnote} + +\usepackage[ +backend=biber, +style=numeric, +]{biblatex} +\addbibresource{sources.bib} + +\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} + +\definecolor{codegreen}{HTML}{49BE25} + +\newtcolorbox{codebox}[1][sidebyside]{ + enhanced,skin=bicolor, + #1, + arc=1pt, + colframe=brown, + colback=brown!15,colbacklower=white, + boxrule=1pt, + notitle +} + +\newtcolorbox{codehead}[1][]{ + enhanced, + frame hidden, + colback=rosegray!15, + boxrule=0mm, + leftrule=5mm, + rightrule=5mm, + boxsep=0mm, + arc=0mm, + outer arc=0mm, + left=3mm, + right=3mm, + top=1mm, + bottom=1mm, + toptitle=1mm, + bottomtitle=1mm, + oversize, + #1 +} + +\usepackage{varwidth} + +\newtcolorbox{newcodehead}[2][]{ + enhanced, + frame hidden, + colback=rosegray!15, + boxrule=0mm, + leftrule=5mm, + rightrule=5mm, + boxsep=0mm, + arc=0mm, + outer arc=0mm, + left=3mm, + right=3mm, + top=1mm, + bottom=1mm, + toptitle=1mm, + bottomtitle=1mm, + oversize, + #1, + fonttitle=\bfseries\ttfamily\footnotesize, + coltitle=rosegray, + attach boxed title to top text right, + boxed title style={frame hidden,size=small,bottom=-1mm, + interior style={fill=none, + top color=white, + bottom color=white}}, + title={#2} +} + +\makeindex + +\newcommand{\coderef}[2]{% +\begin{codehead}[sidebyside,segmentation hidden]% + \mintinline{lua}{#1}% + \tcblower% + \begin{flushright}% + \mintinline{lua}{#2}% + \end{flushright}% +\end{codehead}% +} + +\newcommand{\newcoderef}[3]{% +\begin{newcodehead}[sidebyside,segmentation hidden]{#3}% + \mintinline{lua}{#1}% + \tcblower% + \begin{flushright}% + \mintinline{lua}{#2}% + \end{flushright}% +\end{newcodehead}% +} + +\begin{document} + +\subsection{Core Classes} + +There are several classes in the core module; but only some classes are concrete: + +\begin{multicols}{2} + \begin{center} + \underline{Abstract classes:} + \begin{itemize} + \item \texttt{Expression} + \item \texttt{AtomicExpression} + \item \texttt{CompoundExpression} + \item \texttt{ConstantExpression} + \end{itemize} + + \underline{Concrete classes:} + \begin{itemize} + \item \texttt{SymbolExpression} + \item \texttt{BinaryOperation} + \item \texttt{FunctionExpression} + \end{itemize} +\end{center} +\end{multicols} + +The abstract classes provide a unified interface for the concrete classes (expressions) using inheritance. \emph{Every} expression in \texttt{luacas} inherits from either {\ttfamily AtomicExpression} or {\ttfamily CompoundExpression} which, in turn, inherit from {\ttfamily Expression}. + +\coderef{function SymbolExpression:new(string)}{return SymbolExpression} +\index{Core!Classes!\texttt{SymbolExpression}} +\addcontentsline{toc}{subsubsection}{\ttfamily SymbolExpression} + +Creates a new \texttt{SymbolExpression}. For example: +\begin{codebox}[] +\begin{minted}[breaklines,fontsize=\small]{lua} +foo = SymbolExpression("bar") +tex.sprint("The Lua variable ``foo'' is the SymbolExpression: ", foo:tolatex(),".") +\end{minted} +\tcblower +\directlua{ +foo = SymbolExpression("bar") +tex.sprint("The Lua variable 'foo' is the SymbolExpression: ", foo:tolatex(),".") +} +\end{codebox} + +\subsubsection*{Fields} + +\texttt{SymbolExpression}s have only one field: \texttt{symbol}. In the example above, the string \mintinline{lua}{"bar"} is stored in \mintinline{lua}{foo.symbol}. + +\subsubsection*{Parsing} + +The command \mintinline{lua}{vars()} in \texttt{test.parser} creates a new \texttt{SymbolExpression} for every string in the argument; each such \texttt{SymbolExpression} is assigned to a variable of the same name. For example: + +\begin{minted}{lua} +vars('x','y') +\end{minted} + +is equivalent to: + +\begin{minted}{lua} +x = SymbolExpression("x") +y = SymbolExpression("y") +\end{minted} + +\newcoderef{function BinaryOperation:new(operation, expressions)}{return BinaryOperation}{operation function, expressions table<number,Expression>} +\index{Core!Classes!\texttt{BinaryOperation}} +\addcontentsline{toc}{subsubsection}{\ttfamily BinaryOperation} + +Creates a new \texttt{BinaryOperation} expression. For example: + +\begin{codebox} +\begin{minted}[fontsize=\small]{lua} +vars('x','y','z') +w = BinaryOperation( + BinaryOperation.ADD, + {BinaryOperation( + BinaryOperation.MUL, + {x,y} + ),y,z} +) +tex.print("\\[w=",w:tolatex(),"\\]") +\end{minted} +\tcblower +\directlua{ +vars('x','y','z') +w = BinaryOperation( + BinaryOperation.ADD, + {BinaryOperation( + BinaryOperation.MUL, + {x,y} + ),y,z} +) +tex.print("\\[w=",w:tolatex(),"\\]") +} +\end{codebox} +The variable \texttt{operation} must be a function \mintinline{lua}{function f(a,b)} assigned to one of the following types: +\bgroup +\setdescription{style=multiline, + topsep=10pt, + leftmargin=4.5cm, + font=\ttfamily + } +\begin{description} + \item[BinaryOperation.ADD:] \mintinline{lua}{return a + b} + \item[BinaryOperation.SUB:] \mintinline{lua}{return a - b} + \item[BinaryOperation.MUL:] \mintinline{lua}{return a * b} + \item[BinaryOperation.DIV:] \mintinline{lua}{return a / b} + \item[BinaryOperation.IDIV:] \mintinline{lua}{return a // b} + \item[BinaryOperation.MOD:] \mintinline{lua}{return a % b} + \item[BinaryOperation.POW:] \mintinline{lua}{return a ^ b} +\end{description} +\egroup +The variable \texttt{expressions} must be a table of \texttt{Expression}s index by Lua numbers. + +\subsubsection*{Fields} + +\texttt{BinaryOperation}s have the following fields: \texttt{name}, \texttt{operation}, and \texttt{expressions}. In the example above, we have: +\begin{itemize} + \item the variable \texttt{expressions} is stored in \mintinline{lua}{w.expressions}; + \item \mintinline{lua}{w.name} stores the string \mintinline{lua}{"+"}; and + \item \mintinline{lua}{w.operation} stores the function: + \begin{minted}{lua} +BinaryOperation.ADD = function(a, b) + return a + b +end + \end{minted} +\end{itemize} + +\begin{multicols}{2} +The entries of \texttt{w.expressions} can be used/fetched in a reasonable way: +\begin{codebox}[] + \begin{minted}[fontsize=\small]{latex} +$\print{w.expressions[1]} \quad + \print{w.expressions[2]} \quad + \print{w.expressions[3]}$ + \end{minted} + \tcblower +$\print{w.expressions[1]} \quad + \print{w.expressions[2]} \quad + \print{w.expressions[3]}$ +\end{codebox} + +\begin{center} + \bracketset{action character = @} + \parseshrub{w} + \begin{forest} + for tree = {font = \ttfamily, + draw, + rounded corners = 1pt, + fill = gray!20, + l sep = 1.5cm, + s sep = 2cm} + @\shrubresult + \end{forest} +\end{center} +\end{multicols} + +\subsubsection*{Parsing} + +Thank goodness for this. Creating new \texttt{BinaryOperation}s isn't nearly as cumbersome as the above would indicate. Using Lua's powerful metamethods, we can parse expressions easily. For example, the construction of \texttt{w} given above can be done much more naturally using: +\begin{codebox} +\begin{minted}[fontsize=\small]{lua} +vars('x','y','z') +w = x*y+y+z +tex.print("\\[w=", w:tolatex(), "\\]") +\end{minted} +\tcblower +\directlua{ + vars('x','y','z') + w = x*y+y+z + tex.print("\\[w=", w:tolatex(), "\\]") +} +\end{codebox} +\reversemarginpar +{\bf Warning:}\marginnote{\color{rose}\faExclamationTriangle} There are escape issues to be aware of with the operator \mintinline{latex}{%}. If you're writing custom \texttt{luacas} functions in a separate \texttt{.lua} file, then there are no issues; use \mintinline{latex}{%} with reckless abandon. But when using the operator \mintinline{latex}{%} within, say \mintinline{latex}{\begin{CAS}..\end{CAS}}, then one should write \mintinline{latex}{\%} in place of \mintinline{latex}{%}: + +\begin{codebox} +\begin{minted}[breaklines,fontsize=\small]{latex} +\begin{CAS} + a = 17 + b = 5 + c = a \% b +\end{CAS} +\[ \print{c} \equiv \print{a} \bmod{\print{b}} \] +\end{minted} +\tcblower +\begin{CAS} + a = 17 + b = 5 + c = a \% b +\end{CAS} +\[ \print{c} \equiv + \print{a} \bmod{\print{b}} \] +\end{codebox} +The above escape will {\bf not} work with \mintinline{latex}{\directlua}, but it will work for \mintinline{latex}{\luaexec} from the \texttt{luacode} package. Indeed, the \texttt{luacode} package was designed (in part) to make escapes like this more manageable. Here is the equivalent code using \mintinline{latex}{\luaexec}: +\begin{codebox}[] +\begin{minted}[fontsize=\small]{lua} +a = Integer(17) +b = Integer(5) +c = a \% b +tex.print("\\[",c:tolatex(),"\\equiv",a:tolatex(), "\\bmod{",b:tolatex(),"} \\]") +\end{minted} +\tcblower +\luaexec{ +a = Integer(17) +b = Integer(5) +c = a \% b +tex.print("\\[", c:tolatex(), "\\equiv", a:tolatex(), "\\bmod{", b:tolatex(), "} \\]") +} +\end{codebox} + +\newcoderef{function FunctionExpression:new(name,expressions)}{return FunctionExpression}{name string|SymbolExpression, expressions table<number,Expression>} +\index{Core!Classes!\texttt{FunctionExpression}} +\addcontentsline{toc}{subsubsection}{\ttfamily FunctionExpression} + +Creates a generic function. For example: +\begin{codebox} + \begin{minted}[fontsize=\small]{lua} +vars('x','y') +f = FunctionExpression('f',{x,y}) +tex.print("\\[",f:tolatex(),"\\]") + \end{minted} + \tcblower + \luaexec{ + vars('x','y') + f = FunctionExpression('f',{x,y}) + tex.print("\\[",f:tolatex(),"\\]") + } +\end{codebox} +The variable \texttt{name} can be a string (like above), or another \texttt{SymbolExpression}. But in this case, the variable \texttt{name} just takes the value of the string \mintinline{lua}{SymbolExpression.symbol}. The variable \texttt{expressions} must be a table of \texttt{Expression}s indexed by Lua numbers. + +\subsubsection*{Fields} +\texttt{FunctionExpression}s have the following fields: \texttt{name}, \texttt{expressions}, \texttt{variables}, \texttt{derivatives}. In the example above, we have: +\begin{itemize} + \item the variable \texttt{name}, i.e. the string \mintinline{lua}{'f'}, is stored in \mintinline{lua}{f.name}; and + \item the variable \texttt{expressions}, i.e. the table \mintinline{lua}{{x,y}} is stored in \mintinline{lua}{f.expressions}. +\end{itemize} + +Wait a minute, what about \texttt{variables} and \texttt{derivatives}!? The field \texttt{variables} essentially stores a copy of the variable \texttt{expressions} \textit{as long as} the entries in that table are atomic. If they aren't, then \texttt{variables} will default to $x,y,z$, or $x_1,x_2,\ldots$ if the number of variables exceeds $3$. For example: + +\begin{codebox} + \begin{minted}[fontsize=\small]{lua} +vars('s','t') +f = FunctionExpression('f',{s*s,s+t+t}) +tex.print("The variables of f are:") +for _,symbol in ipairs(f.variables) do + tex.print(symbol:tolatex()) +end + \end{minted} + \tcblower +\luaexec{ + vars('s','t') + f = FunctionExpression('f',{s*s,s+t+t}) + tex.print("The variables of f are:") + for _,symbol in ipairs(f.variables) do + tex.print(symbol:tolatex()) + end +} +\end{codebox} +The field \texttt{derivatives} is a table of \texttt{Integer}s indexed by Lua numbers whose length equals \mintinline{lua}{#o.variables}. The default value for this table is a table of (\texttt{Integer}) zeros. So for the example above, we have: +\begin{codebox} + \begin{minted}[fontsize=\small]{lua} +for _,integer in ipairs(f.derivatives) do + if integer == Integer.zero() then + tex.print("I'm a zero.\\newline") + end +end +\end{minted} +\tcblower +\luaexec{ + for _,integer in ipairs(f.derivatives) do + if integer == Integer.zero() then + tex.print("I'm a zero.\\newline") + end + end +} +\end{codebox} +We can change the values of \texttt{variables} and \texttt{derivatives} manually (or more naturally by other gizmos found in \texttt{luacas}). For example, keeping the variables from above, we have: +\begin{multicols}{2} +\begin{codebox}[] + \begin{minted}[fontsize=\small]{lua} +f.derivatives = {Integer.one(), + Integer.one()} +tex.print("\\[", + f:simplify():tolatex(), + "\\]") +\end{minted} +\tcblower +\luaexec{ + f.derivatives = {Integer.one(),Integer.one()} + tex.print("\\[", f:simplify():tolatex(), "\\]") +} +\end{codebox} + +\begin{center} +\parseshrub{f} +\bracketset{action character = @} +\begin{forest} + for tree = {font = \ttfamily, + draw, + rounded corners = 1pt, + fill = gray!20, + l sep = 1.5cm, + s sep = 0.75cm} + @\shrubresult +\end{forest} +\end{center} +\end{multicols} + +\subsubsection*{Parsing} + +Thank goodness for this too. The parser nested within the \LaTeX{} environment \mintinline{latex}{\begin{CAS}..\end{CAS}} allows for fairly natural function assignment; the name of the function must be declared in \mintinline{lua}{vars(...)} (or rather, as a \texttt{SymbolExpression}) beforehand: +\begin{codebox} + \begin{minted}[fontsize=\small]{latex} +\begin{CAS} + vars('s','t','f') + f = f(s^2,s+2*t) + f.derivatives = {1,1} +\end{CAS} +\[ \print{f} \] +\end{minted} +\tcblower +\begin{CAS} + vars('s','t','f') + f = f(s^2,s+2*t) + f.derivatives = {1,1} +\end{CAS} +\[ \print{f} \] +\end{codebox} + +\end{document}
\ No newline at end of file |