summaryrefslogtreecommitdiff
path: root/doc/context/sources/general/manuals/metafun/metafun-functions.tex
diff options
context:
space:
mode:
Diffstat (limited to 'doc/context/sources/general/manuals/metafun/metafun-functions.tex')
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-functions.tex611
1 files changed, 611 insertions, 0 deletions
diff --git a/doc/context/sources/general/manuals/metafun/metafun-functions.tex b/doc/context/sources/general/manuals/metafun/metafun-functions.tex
new file mode 100644
index 000000000..780127408
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-functions.tex
@@ -0,0 +1,611 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-functions
+
+\environment metafun-environment
+
+\startchapter[title={Functions}]
+
+\index{functions}
+
+\startintro
+
+\METAPOST\ provides a wide range of functions, like \type {sind} and \type
+{floor}. We will discuss most of them here and define a few more. We will also
+introduce a few methods for drawing grids and functions.
+
+\stopintro
+
+\startsection[title={Overview}]
+
+What follows is a short overview of the functions that can be applied to numeric
+expressions and strings. Functions that operate on pairs, colors, paths and
+pictures are discussed in other chapters.
+
+First of all we have \type {+}, \type {-}, \type {/} and \type {*}. For as far as
+is reasonable, you can apply these to numerics, pairs and colors. Strings can be
+concatenated by \type {&}.
+
+Pythagorean addition is accomplished by \type {++}, while Pythagorean subtraction
+is handled by \type {+-+}. The \type {**} operator gives you exponentiation. The
+nature of the \METAPOST\ language is such that you can easily define interesting
+functions using such symbols.
+
+The logarithmic functions are based on bytes. This makes them quite accurate but
+forces you to think like a computer.
+
+\starttabulate[|lT|l|]
+\HL
+\NC mexp(x) \NC expential function with base 256 \NC \NR
+\NC mlog(x) \NC logarithm with base 256 \NC \NR
+\HL
+\stoptabulate
+
+The basic goniometric functions operate on degrees, which is why they have a
+\quote {d} in their name.
+
+\starttabulate[|lT|l|]
+\HL
+\NC cosd(x) \NC cosine of $x$ with $x$ in degrees \NC \NR
+\NC sind(x) \NC sine of $x$ with $x$ in degrees \NC \NR
+\HL
+\stoptabulate
+
+There are three ways to truncate numbers. The \type {round} function can also
+handle pairs and colors.
+
+\starttabulate[|lT|l|]
+\HL
+\NC ceiling(x) \NC the least integer greater than or equal to $x$ \NC \NR
+\NC floor(x) \NC the greatest integer less than or equal to $x$ \NC \NR
+\NC round(x) \NC round each component of $x$ to the nearest integer \NC \NR
+\HL
+\stoptabulate
+
+Of course we have:
+
+\starttabulate[|lT|l|]
+\HL
+\NC x mod y \NC the remainder of $x/y$ \NC \NR
+\NC x div y \NC the integer part of $x/y$ \NC \NR
+\NC abs(x) \NC the absolute value of $x$ \NC \NR
+\NC sqrt(x) \NC the square root of $x$ \NC \NR
+\NC x dotprod y \NC the dot product of two vectors \NC \NR
+\HL
+\stoptabulate
+
+What would life be without a certain randomness and uncertainty:
+
+\starttabulate[|lT|l|]
+\HL
+\NC normaldeviate \NC a number with mean 0 and standard deviation 1 \NC \NR
+\NC uniformdeviate(x) \NC a number between zero and $x$ \NC \NR
+\HL
+\stoptabulate
+
+The following functions are actually macros:
+
+\starttabulate[|lT|l|]
+\HL
+\NC decr(x,n) \NC decrement $x$ by $n$ \NC \NR
+\NC incr(x,n) \NC increment $x$ by $n$ \NC \NR
+\NC max(a,b,..) \NC return the maximum value in the list \NC \NR
+\NC min(a,b,..) \NC return the minimum value in the list \NC \NR
+\HL
+\stoptabulate
+
+The \type {min} and \type {max} funtions can be applied to numerics as well as
+strings.
+
+The following functions are related to strings:
+
+\starttabulate[|lT|l|]
+\HL
+\NC oct s \NC string representation of an octal number \NC \NR
+\NC hex s \NC string representation of a hexadecimal number \NC \NR
+\NC str s \NC string representation for a suffix \NC \NR
+\NC ASCII s \NC \ASCII\ value of the first character \NC \NR
+\NC char x \NC character of the given \ASCII\ code \NC \NR
+\NC decimal x \NC decimal representation of a numeric \NC \NR
+\HL
+\stoptabulate
+
+With \type {substring (i,j) of s} you can filter the substring bounded by the
+given indices from the given string.
+
+In \METAFUN\ we provide a few more functions (you can take a look in \type
+{mp-tool.mp} to see how they are defined. You need to be aware of very subtle
+rounding errors. Normally these only show up when you reverse an operation. This
+is a result from mapping to and from internal quantities.
+
+\starttabulate[|Tl|ml|]
+\HL
+\NC sqr(x) \NC x^2 \NC \NR
+\NC log(x) \NC \log(x) \NC \NR
+\NC ln(x) \NC \ln(x) \NC \NR
+\NC exp(x) \NC {\rm e}^x \NC \NR
+\NC pow(x, p) \NC x^p \NC \NR
+\NC inv(x) \NC 1/x \NC \NR
+\HL
+\stoptabulate
+
+The following sine and cosine functions take radians instead of angles in
+degrees.
+
+\starttabulate[|Tl|Tl|Tl|]
+\HL
+\NC sin(x) \NC asin(x) \NC invsin(x) \NC \NR
+\NC cos(x) \NC acos(x) \NC invcos(x) \NC \NR
+\HL
+\stoptabulate
+
+There are no tangent functions, so we provide both the radian and degrees
+versions:
+
+\starttabulate[|Tl|Tl|]
+\HL
+\NC tan(x) \NC tand(x) \NC \NR
+\NC cot(x) \NC cotd(x) \NC \NR
+\HL
+\stoptabulate
+
+Here are a couple of hyperbolic functions.
+
+\starttabulate[|Tl|Tl|]
+\HL
+\NC sinh(x) \NC asinh(x) \NC \NR
+\NC cosh(x) \NC acosh(x) \NC \NR
+\HL
+\stoptabulate
+
+We end with a few additional string converters.
+
+\starttabulate[|Tl|l|]
+\HL
+\NC ddecimal x \NC decimal representation of a pair \NC \NR
+\NC dddecimal x \NC decimal representation of a color \NC \NR
+\NC condition x \NC string representation of a boolean \NC \NR
+\HL
+\stoptabulate
+
+\stopsection
+
+\startsection[title={Grids}]
+
+\index{grids}
+\index{axis}
+
+Some day you may want to use \METAPOST\ to draw a function like graphic. In the
+regular \TEX\ distributions you will find a module \type {graph.mp} that provides
+many ways to accomplish this. For the moment, \METAFUN\ does not provide advanced
+features with respect to drawing functions, so this section will be relatively
+short.
+
+When drawing a functions (for educational purposes) we need to draw a couple of
+axis or a grid as well as a shape. Along the axis we can put labels. For this we
+can use the \METAPOST\ package \type {format.mp}, but this does not integrate
+that well into the way \METAFUN\ deals with text typeset by \TEX.
+
+For those who love dirty tricks and clever macros, close reading of the code in
+\type {format.mp} may be worthwhile. The format macros in there use \TEX\ to
+typeset the core components of a number, and use the dimensions of those
+components to compose combinations of signs, numbers and superscripts.
+
+In \METAFUN\ we have the module \type {mp-form.mp} which contains most of the
+code in \type {format.mp} but in a form that is a bit more suited for fine
+tuning. This permits us to use either the composition method, or to fall back on
+the \type {textext} method that is part of \METAFUN. That way we can also handle
+fonts that have digits with different dimensions. Another \quote {change}
+concerns the pattern separator. Instead of a \type {%} we use \type {@}; you can
+choose to set another separator, but for embedded definitions \type {%} is
+definitely a bad choice because \TEX\ sees it as a comment and ignores everything
+following it.
+
+\startbuffer[grd]
+drawoptions(withpen pencircle scaled 1pt withcolor .625yellow) ;
+
+draw hlingrid(0, 10, 1, 3cm, 3cm) ;
+draw vlingrid(0, 10, 1, 3cm, 3cm) ;
+
+draw hlingrid(0, 10, 1, 3cm, 3cm) shifted ( 3.5cm,0) ;
+draw vloggrid(0, 10, 1, 3cm, 3cm) shifted ( 3.5cm,0) ;
+
+draw hloggrid(0, 10, 1, 3cm, 3cm) shifted ( 7.0cm,0) ;
+draw vlingrid(0, 10, 1, 3cm, 3cm) shifted ( 7.0cm,0) ;
+
+draw hloggrid(0, 10, 1, 3cm, 3cm) shifted (10.5cm,0) ;
+draw vloggrid(0, 10, 1, 3cm, 3cm) shifted (10.5cm,0) ;
+\stopbuffer
+
+\typebuffer[grd]
+
+\startlinecorrection[blank]
+\processMPbuffer[grd]
+\stoplinecorrection
+
+\startbuffer[grd]
+drawoptions(withpen pencircle scaled 1pt withcolor .625yellow) ;
+
+draw hlingrid(0, 10, 1, 3cm, 3cm) slanted .5 ;
+draw vlingrid(0, 10, 1, 3cm, 3cm) slanted .5 ;
+\stopbuffer
+
+\typebuffer[grd]
+
+\startlinecorrection[blank]
+\processMPbuffer[grd]
+\stoplinecorrection
+
+Using macros like these often involves a bit of trial and error. The arguments to
+these macros are as follows:
+
+\starttyping
+hlingrid (Min, Max, Step, Length, Width)
+vlingrid (Min, Max, Step, Length, Height)
+hloggrid (Min, Max, Step, Length, Width)
+vloggrid (Min, Max, Step, Length, Height)
+\stoptyping
+
+The macros take the following text upto the semi||colon into account and return a
+picture. We will now apply this knowledge to a more meaningful example. First we
+draw a grid.
+
+You can use the grid drawing macros to produce your own paper, for instance using
+the following mixed \TEX ||\METAFUN\ code:
+
+\typebuffer[gridpage]
+
+This produces a page (as in \in {figure} [fig:gridpage]) with a metric grid. If
+you're hooked to the inch, you can set \type {unit := 1in}. If you want to
+process this code, you need to wrap it into the normal document producing
+commands:
+
+\starttyping
+\setupcolors[state=start]
+
+\starttext
+ ... definitions ...
+\stoptext
+\stoptyping
+
+\placefigure
+ [page]
+ [fig:gridpage]
+ {Quick and dirty grid paper.}
+ {\typesetfile
+ [mfun-901.tex]
+ [page=1,height=.9\textheight]}
+
+\stopsection
+
+\startsection[title={Drawing functions}]
+
+Today there are powerful tools to draw functions on grids, but for simple
+functions you can comfortably use \METAPOST. Let's first draw a simple
+log||linear grid.
+
+\startbuffer[grd]
+drawoptions(withpen pencircle scaled .25pt withcolor .5white) ;
+
+draw hlingrid (0, 20, .2, 20cm, 10cm) ;
+draw vloggrid (0, 10, .5, 10cm, 20cm) ;
+
+drawoptions(withpen pencircle scaled .50pt) ;
+
+draw hlingrid (0, 20, 1, 20cm, 10cm) ;
+draw vloggrid (0, 10, 1, 10cm, 20cm) ;
+\stopbuffer
+
+\typebuffer[grd]
+
+To this grid we add some labels:
+
+\startbuffer[txt]
+fmt_pictures := false ; % use TeX as formatting engine
+textextoffset := ExHeight ; % a variable set by ConTeXt
+
+draw hlintext.lft(0, 20, 5, 20cm, "@3e") ;
+draw vlogtext.bot(0, 10, 9, 10cm, "@3e") ;
+\stopbuffer
+
+\typebuffer[txt]
+
+The arguments to the text placement macros are similar to the ones for drawing
+the axes. Here we provide a format string.
+
+\starttyping
+hlintext (Min, Max, Step, Length, Format)
+vlintext (Min, Max, Step, Length, Format)
+hlogtext (Min, Max, Step, Length, Format)
+vlogtext (Min, Max, Step, Length, Format)
+\stoptyping
+
+When drawing a smooth function related curve, you need to provide enough sample
+points. The \type {function} macro will generate them for you, but you need to
+make sure that for instance the maximum and minimum values are part of the
+generated series of points. Also, a smooth curve is not always the right curve.
+Therefore we provide three drawing modes:
+
+\starttabulate[|cT|l|]
+\HL
+\NC \bf method \NC \bf result \NC \NR
+\HL
+\NC 1 \NC a punked curve, drawn using \type {--} \NC \NR
+\NC 2 \NC a smooth curve, drawn using \type {..} \NC \NR
+\NC 3 \NC a tight curve, drawn using \type {...} \NC \NR
+\HL
+\stoptabulate
+
+If method~2 or~3 do not give the desired outcome, you can try a smaller step
+combined with method~1.
+
+\startbuffer[log]
+draw
+ function(1,"log(x)","x",1,10,1) xyscaled (10cm,2cm)
+ withpen pencircle scaled 5mm withcolor transparent(1,.5,yellow) ;
+
+draw
+ function(2,".5log(x)","x",1,10,1) xyscaled (10cm,2cm)
+ withpen pencircle scaled 5mm withcolor transparent(1,.5,blue) ;
+\stopbuffer
+
+\typebuffer[log]
+
+\placefigure
+ [page]
+ {An example of a graphic with labels along the axes.}
+ {\doifmodeelse{screen}
+ {\scale[height=.85\textheight]{\processMPbuffer[grd,txt,log]}}
+ {\processMPbuffer[grd,txt,log]}}
+
+The first argument to the \type {function} macro specifies the drawing method.
+The last three arguments are the start value, end value and step. The second and
+third argument specify the function to be drawn. In this case the pairs \type
+{(x,x)} and \type {(.5log(x),x)} are calculated.
+
+\startbuffer[gon]
+textextoffset := ExHeight ;
+
+drawoptions(withpen pencircle scaled .50pt) ;
+
+draw hlingrid(-10, 10, 1, 10cm, 10cm) ;
+draw vlingrid( 0, 20, 1, 10cm, 20cm) shifted (0,-10cm) ;
+
+drawoptions() ;
+
+draw
+ function(2,"x","sind(x)",0,360,10) xyscaled (1cm/36,10cm)
+ withpen pencircle scaled 5mm withcolor transparent(1,.5,blue) ;
+
+draw
+ function(2,"x","sin(x*pi)",0,epsed(2),.1) xyscaled (10cm/2,5cm)
+ withpen pencircle scaled 5mm withcolor transparent(1,.5,yellow) ;
+
+draw
+ function(2,"x","cosd(x)",0,360,10) xyscaled (1cm/36,10cm)
+ withpen pencircle scaled 5mm withcolor transparent(1,.5,red) ;
+
+draw
+ function(2,"x","cos(x*pi)",0,epsed(2),.1) xyscaled (10cm/2,5cm)
+ withpen pencircle scaled 5mm withcolor transparent(1,.5,green) ;
+\stopbuffer
+
+\typebuffer[gon]
+
+\placefigure
+ [page]
+ {By using transparent colors, we don't have to calculate
+ and mark the common points: they already stand out.}
+ {\doifmodeelse{screen}
+ {\scale[height=.85\textheight]{\processMPbuffer[gon]}}
+ {\processMPbuffer[gon]}}
+
+In this example we draw sinus and cosine functions using degrees and radians. In
+the case of radians the end points are not calculated due to rounding errors. In
+such case you can use the \type {epsed} value, which gives slightly more
+playroom.
+
+\startbuffer[mix]
+draw function (1, "x", "sin(2x)" , 1, 10, .01) scaled 1.5cm
+ withpen pencircle scaled 1mm withcolor transparent(1,.5,red) ;
+draw function (1, "x", "sin(2x*x)" , 1, 10, .01) scaled 1.5cm
+ withpen pencircle scaled 1mm withcolor transparent(1,.5,green) ;
+draw function (1, "x", "sin(2x*x+x)", 1, 10, .01) scaled 1.5cm
+ withpen pencircle scaled 1mm withcolor transparent(1,.5,blue) ;
+\stopbuffer
+
+\typebuffer[mix]
+
+Of course you can do without a grid. The next example demonstrates a nice
+application of transparencies.
+
+\startlinecorrection[blank]
+\processMPbuffer[mix]
+\stoplinecorrection
+
+If we use the \type {exclusion} method for the transparencies, combined with no
+transparency, we get the following alternative.
+
+\startbuffer[mix]
+draw function (2, "x", "sin(x)" , 0, 2pi, pi/40) scaled 2cm
+ withpen pencircle scaled 5mm withcolor transparent("exclusion",1,red) ;
+draw function (2, "x", "sin(2x)", 0, 2pi, pi/40) scaled 2cm
+ withpen pencircle scaled 5mm withcolor transparent("exclusion",1,green) ;
+draw function (2, "x", "sin(3x)", 0, 2pi, pi/40) scaled 2cm
+ withpen pencircle scaled 5mm withcolor transparent("exclusion",1,blue) ;
+\stopbuffer
+
+\typebuffer[mix]
+
+\startlinecorrection[blank]
+\processMPbuffer[mix,wipe]
+\stoplinecorrection
+
+The next alternative uses a larger step, and as a result (in drawing mode~2)
+gives worse results. (Without the \type {epsed} it would have looked even worse
+in the end points.
+
+ \startbuffer[mix]
+draw function (2, "x", "sin(x)" , 0, epsed(2pi), pi/10) scaled 2cm
+ withpen pencircle scaled 5mm withcolor transparent("exclusion",1,red) ;
+draw function (2, "x", "sin(2x)", 0, epsed(2pi), pi/10) scaled 2cm
+ withpen pencircle scaled 5mm withcolor transparent("exclusion",1,green) ;
+draw function (2, "x", "sin(3x)", 0, epsed(2pi), pi/10) scaled 2cm
+ withpen pencircle scaled 5mm withcolor transparent("exclusion",1,blue) ;
+\stopbuffer
+
+\typebuffer[mix]
+
+\startlinecorrection[blank]
+\processMPbuffer[mix,wipe]
+\stoplinecorrection
+
+There are enough applications out there to draw nice functions, like gnuplot for
+which Mojca Miklavec made a backend that works well with \CONTEXT. Nevertheless
+it can be illustrative to explore the possibilities of the \CONTEXT, \LUATEX,
+\METAPOST\ combination using functions.
+
+First of all you can use \LUA\ to make paths and this is used in some of the
+debugging and tracing options that come with \CONTEXT. For instance, if you
+process a document with
+
+\starttyping
+context --timing yourdoc.tex
+\stoptyping
+
+then you can afterwards process a file that is generated while processing this
+document:
+
+\starttyping
+context --extras timing yourdoc
+\stoptyping
+
+This will give you a document with graphics that show where \LUATEX\ spent its
+time on. Of course these graphics are generated with \METAPOST.
+
+There are a few helpers built in (and more might follow). For example:
+
+\startbuffer
+draw
+ \ctxlua {
+ metapost.metafun.topath {
+ { x=1, y=1 },
+ { x=1, y=3 },
+ { 4, 1},
+ "cycle"
+ }
+ }
+ xysized(4cm,3cm)
+ withpen pencircle scaled 1mm
+ withcolor .625 red ;
+\stopbuffer
+
+\typebuffer
+
+The \type {topath} function takes a table of points or strings.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+You can pass a connector so
+
+\startbuffer
+draw
+ \ctxlua {
+ metapost.metafun.topath (
+ {
+ { x=1, y=1 },
+ { x=1, y=3 },
+ { 4, 1 },
+ "cycle"
+ },
+ "--"
+ )
+ }
+ xysized(4cm,3cm)
+ withpen pencircle scaled 1mm
+ withcolor .625 red ;
+\stopbuffer
+
+\typebuffer
+
+gives:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Writing such \LUA\ functions is no big deal. For instance we have available:
+
+\starttyping
+function metapost.metafun.interpolate(f,b,e,s,c)
+ tex.write("(")
+ for i=b,e,(e-b)/s do
+ local d = loadstring (
+ string.formatters["return function(x) return %s end"](f)
+ )
+ if d then
+ d = d()
+ if i > b then
+ tex.write(c or "...")
+ end
+ tex.write(string.formatters["(%F,%F)"](i,d(i)))
+ end
+ end
+ tex.write(")")
+end
+\stoptyping
+
+An example of usage is:
+
+\startbuffer
+draw
+ \ctxlua{metapost.metafun.interpolate(
+ "math.sin(x^2+2*x+math.sqrt(math.abs(x)))",
+ -math.pi/2,math.pi/2,100
+ )}
+ xysized(6cm,3cm)
+ withpen pencircle scaled 1mm
+ withcolor .625 red ;
+\stopbuffer
+
+\typebuffer
+
+And indeed we get some drawing:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Let's see what happens when we use less accuracy and a different connector:
+
+\startbuffer
+draw
+ \ctxlua{metapost.metafun.interpolate(
+ "math.sin(x^2+2*x+math.sqrt(math.abs(x)))",
+ -math.pi/2,math.pi/2,10,"--"
+ )}
+ xysized(6cm,3cm)
+ withpen pencircle scaled 1mm
+ withcolor .625 red ;
+\stopbuffer
+
+\typebuffer
+
+Now we get:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Of course we could extend this \LUA\ function with all kind of options and we
+might even do that when we need it.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent