summaryrefslogtreecommitdiff
path: root/graphics/pgf/base/doc/pgfmanual-en-math-algorithms.tex
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/pgf/base/doc/pgfmanual-en-math-algorithms.tex')
-rw-r--r--graphics/pgf/base/doc/pgfmanual-en-math-algorithms.tex231
1 files changed, 231 insertions, 0 deletions
diff --git a/graphics/pgf/base/doc/pgfmanual-en-math-algorithms.tex b/graphics/pgf/base/doc/pgfmanual-en-math-algorithms.tex
new file mode 100644
index 0000000000..9a4daeeaff
--- /dev/null
+++ b/graphics/pgf/base/doc/pgfmanual-en-math-algorithms.tex
@@ -0,0 +1,231 @@
+% Copyright 2019 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Free Documentation License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+
+\section{Customizing the Mathematical Engine}
+\label{pgfmath-reimplement}
+
+Perhaps you have a desire for some function that \pgfname\ does not provide.
+Perhaps you are not happy with the accuracy or efficiency of some of the
+algorithms that are implemented in \pgfname. In these cases you will want to
+add a function to the parser or replace the current implementations of the
+algorithms with your own code.
+
+The mathematical engine was designed with such customization in mind. It is
+possible to add new functions, or modify the code for existing functions. Note,
+however, that whilst adding new operators is possible, it can be a rather
+tricky business and is only recommended for adventurous users.
+
+To add a new function to the math engine the following command can be used:
+
+\begin{command}{\pgfmathdeclarefunction\opt{|*|}\marg{function name}\marg{number of arguments}\marg{code}}
+ This will set up the parser to recognize a function called \meta{name}. The
+ name of the function can consist of, uppercase or lowercase letters,
+ numbers or the underscore |_|. In line with many programming languages, a
+ function name cannot begin with a number or contain any spaces. The
+ function may not have been declared earlier, unless the optional star (|*|)
+ is provided, which forces an ``overwriting'' of the function by the new
+ function. Note that you \emph{should never change the arity of standard
+ functions} and you should normally use |\pgfmathredeclarefunction|,
+ which does not allow you to do anything wrong here.
+
+ The \meta{number of arguments} can be any positive integer, zero, or the
+ value |...|, which indicates a variable number of arguments. \pgfname{}
+ treats constants, such as |pi| and |e|, as functions with zero arguments.
+ Functions with more than nine arguments or with a variable number of
+ arguments are a ``bit special'' and are discussed below.
+
+ The effect of \meta{code} should be to set the macro |\pgfmathresult| to
+ the correct value (namely to the result of the computation without units).
+ Furthermore, the function should have no other side effects, that is, it
+ should not change any global values. As an example, consider the creation
+ of a new function |double|, which takes one argument, and returns the value
+ of that argument times two.
+ %
+\begin{codeexample}[]
+\makeatletter
+\pgfmathdeclarefunction{double}{1}{
+ \begingroup
+ \pgf@x=#1pt\relax
+ \multiply\pgf@x by2\relax
+ \pgfmathreturn\pgf@x
+ \endgroup
+}
+\makeatother
+\pgfmathparse{double(44.3)}\pgfmathresult
+\end{codeexample}
+
+ The macro |\pgfmathreturn|\meta{tokens} must be
+ directly followed by an |\endgroup| and will save the result of the
+ computation, by defining |\pgfmathresult| as the expansion of
+ \meta{tokens} (without units) outside the group, so \meta{tokens}
+ must be something that can be assigned to a dimension register.
+
+ Alternatively, the |\pgfmathsmuggle|\meta{macro} can be used. This must
+ also be directly followed by an |\endgroup| and will simply ``smuggle'' the
+ definition of \meta{macro} outside the \TeX-group.
+
+ By performing computations within a \TeX-group, \pgfname{} registers such
+ as |\pgf@x|, |\pgf@y| and |\c@pgf@counta|, |\c@pgfcountb|, and so forth,
+ can be used at will.
+
+ Beyond setting up the parser, this command also defines two macros which
+ provide access to the function independently of the parser:
+ %
+ \begin{itemize}
+ \item |\pgfmath|\meta{function name}
+
+ This macro will provide a ``public'' interface for the function
+ \meta{function name} allowing the function to be called
+ independently of the parser. All arguments passed to this macro are
+ evaluated using |\pgfmathparse| and then passed on to the following
+ macro:
+ \item |\pgfmath|\meta{function name}|@|
+
+ This macro is the ``private'' implementation of the function's
+ algorithm (but note that, for speed, the parser calls this macro
+ rather than the ``public'' one). Arguments passed to this macro are
+ expected to be numbers without units. It is defined using
+ \meta{code}, but need not be self-contained.
+ \end{itemize}
+
+ For functions that are declared with less than ten arguments, the public
+ macro is defined in the same way as normal \TeX{} macros using, for
+ example, |\def\pgfmathNoArgs{|\meta{code}|}| for a function with no
+ arguments, or |\def\pgfmathThreeArgs#1#2#3{|\meta{code}|}| for a function
+ with three arguments. The private macro is defined in the same way, and
+ each argument can therefore be accessed in \meta{code} using |#1|, |#2| and
+ so on.
+
+ For functions with more than nine arguments, or functions with a variable
+ number of arguments, these macros are only defined as taking \emph{one}
+ argument. The public macro expects its arguments to be comma separated, for
+ example, |\pgfmathVariableArgs{1.1,3.5,-1.5,2.6}|. Each argument is parsed
+ and passed on to the private macro as follows:
+ |\pgfmathVariableArgs@{{1.1}{3.5}{-1.5}{2.6}}|. This means that some
+ ``extra work'' will be required to access each argument (although it is a
+ fairly simple task).
+
+ Note that there are two exceptions to this arrangement: the public versions
+ of the |min| and |max| functions still take two arguments for compatibility
+ with older versions, but each of these arguments can take several comma
+ separated values.
+\end{command}
+
+To redefine a function use the following command:
+
+\begin{command}{\pgfmathredeclarefunction\marg{function name}\marg{code}}
+ This command redefines the |\pgfmath|\meta{function name}|@| macro with the
+ new \meta{code}. See the description of the
+ |\pgfmathdeclarefunction| for details. You cannot change the number of
+ arguments for an existing function.
+ %
+\begin{codeexample}[]
+\makeatletter
+\pgfmathdeclarefunction{foo}{1}{
+ \begingroup
+ \pgf@x=#1pt\relax
+ \multiply\pgf@x by2\relax
+ \pgfmathreturn\pgf@x
+ \endgroup
+}
+\pgfmathparse{foo(42)}\pgfmathresult
+\pgfmathredeclarefunction{foo}{
+ \begingroup
+ \pgf@x=#1pt\relax
+ \multiply\pgf@x by3\relax
+ \pgfmathreturn\pgf@x
+ \endgroup
+}
+\pgfmathparse{foo(42)}\pgfmathresult
+\makeatother
+\end{codeexample}
+ %
+\end{command}
+
+ \pgfname{} uses the last known definition of a function within the
+ prevailing scope, so it is possible for a function to be redefined locally.
+ You should also remember that any |.sty| or |.tex| file containing any
+ re-implementations should be loaded after |pgfmath|.
+
+ In addition to the above commands, the following key is provided to quickly
+ create simple ad hoc functions which can greatly improve the readability of
+ code, and is particularly useful in \tikzname{}:
+
+\begin{key}{/pgf/declare function=\meta{function definitions}}
+ This key allows simple functions to be created locally. Its use is perhaps
+ best illustrated by an example:
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}
+ \draw [help lines] (0,0) grid (3,2);
+ \draw [blue, thick, x=0.0085cm, y=1cm,
+ declare function={
+ sines(\t,\a,\b)=1 + 0.5*(sin(\t)+sin(\t*\a)+sin(\t*\b));
+ }]
+ plot [domain=0:360, samples=144, smooth] (\x,{sines(\x,3,5)});
+\end{tikzpicture}
+\end{codeexample}
+
+ Each definition in \meta{function definitions} takes the form
+ \meta{name}|(|\meta{arguments}|)=|\meta{definition}|;| (note the semicolon
+ at the end, this is very important). If multiple functions are being
+ defined, the semicolon is used to separate them (\emph{not} a comma). The
+ function \meta{name} can be any name that is not already a function name in
+ the current scope. The list of \meta{arguments} are commands such as |\x|,
+ or |\y| (it is not possible to declare functions that take variable numbers
+ of arguments using this key). If the function takes no arguments, then the
+ parentheses need not be used. The \meta{definition} should be an expression
+ that can be parsed by the mathematical engine and should use the commands
+ specified in \meta{arguments}.
+
+ When specifying multiple functions, functions that appear later on in
+ \meta{function definitions} can refer to earlier functions:
+ %
+\begin{codeexample}[pre={\pgfmathsetseed{1}}]
+\begin{tikzpicture}[
+ declare function={
+ excitation(\t,\w) = sin(\t*\w);
+ noise = rnd - 0.5;
+ source(\t) = excitation(\t,20) + noise;
+ filter(\t) = 1 - abs(sin(mod(\t, 90)));
+ speech(\t) = 1 + source(\t)*filter(\t);
+ }
+]
+ \draw [help lines] (0,0) grid (3,2);
+ \draw [blue, thick, x=0.0085cm, y=1cm] (0,1) --
+ plot [domain=0:360, samples=144, smooth] (\x,{speech(\x)});
+\end{tikzpicture}
+\end{codeexample}
+ %
+\end{key}
+
+\begin{key}{/pgf/declare function/execute at begin function=\meta{tokens}}
+ These \meta{tokens} are inserted just before |\pgfmathdeclarefunction|
+ scans the body of the function definition. This is a rather low-level
+ option, so you should read the implementation to figure out where the
+ \meta{tokens} are inserted.
+\end{key}
+
+\begin{key}{/pgf/declare function/execute at end function=\meta{tokens}}
+ These \meta{tokens} are inserted just after |\pgfmathdeclarefunction| has
+ finished scanning the body of the function definition. This is a rather
+ low-level option, so you should read the implementation to figure out where
+ the \meta{tokens} are inserted.
+\end{key}
+
+\begin{key}{/pgf/declare function/ignore spaces=\meta{boolean}}
+ Uses the two previously described keys |/pgf/declare function/execute at begin function| and
+ |/pgf/declare function/execute at end function| to install catcodes such
+ that spaces inside the body of the function definition of
+ |\pgfmathdeclarefunction| are ignored. The usual \TeX\ tokenization rules
+ apply, so if the body of the function had already been tokenized by other
+ means this will become ineffective. If you want to use a space you can use
+ |~| in the function body which has its catcode set to 10 (space).
+\end{key}