# Functions and text

## Functions

MetaPost lets users define their own functions through variable macros using the `vardef` keyword.

Lets define and draw the probability density function of the standard normal deviation.

``````vardef std_normal(expr x) =
e:=2.7182;
pi:=3.1415;
(1/sqrt(2*pi))*(e**-((x**2)/2))
enddef;``````

Notice that ** has the same precedence as * in metapost so the parentheses are needed.

Now we can use a For loop to draw the function:

``````  draw ((-4,std_normal(-4)) for i:=-3.9 step 0.1 until 4:
..(i,std_normal(i)) endfor) scaled 2u yscaled u;``````

this gets a bit long if we are drawing several functions, so lets define a macro to draw out math functions. Since we don't have functions as such, but only macros we can't easily pass functions as input into other functions. But there is a way. In order to pass macros to other macros we can use the `scantokens` (string) function. This tell MetaPost to interpret a string as if it was a MetaPost command.

``````vardef functionpath (expr func, a, b) =
((a, scantokens func(a)) for i:=a step (1/(10(b-a))) until b:
..(i,scantokens func(i)) endfor)
enddef;``````

We can then replace our draw code with a call to the macro, maybe in a for loop. Of course we now have to remember to pass our macro name as a string as expected by `scantokens`.

``````  for i:=0 upto 5:
draw functionpath("std_normal", -4, 4) scaled 2u yscaled u shifted (i*u,0);
endfor;``````

## Text

MetaPost is often used to make figures for LaTeX documents, but in turn MetaPost also uses LaTeX to typeset text. You can do some simple text as we have seen already by just putting in strings. But if you need to include variables in your strings, or just have more control of how the text looks MetaPost uses LaTeX to compile our text into images. There are a few different ways to put input LaTeX strings in your figures, but the one I find easiest and most powerful is with the `TEX.mp` utility library.

`TEX.mp` is simply a MetaPost file thats is distributed with metapost, you should be able to load in into your session by including the line

``input TEX;``

Once this file is loaded you can use the `TEX` function to typeset labels with LaTeX commands. The `TEX` function expects a LaTeX formatted string, to embed MetaPost variables into the string use `&` for appending and `decimal(x)` to cast the `numeric` `x` into the `decimal` type which is compatible with string embedding. For example we can add a labeled x-axis to our figure:

``````drawarrow (-1.5,0)--(1.5,0);
for i:= -1.5 step 0.5 until 1.5:
label(TEX("\$"&decimal(i)&"\$"),(i,0));
endfor``````

## Exercise

Define you own mathematical function using `vardef` and draw it out, add some LaTeX formatted labels to your figure using the `TEX` command.

### Hint

``````outputformat := "png";
outputtemplate := "%j_%c.png";
hppp := 0.25;
vppp := 0.25;
u:=0.5cm;
input TEX;

vardef fun (expr x)=
(x**2)*u/10
enddef;

beginfig(1)
for i:=0 upto 10:
draw (0,i*u)--(10u,i*u);
draw (i*u,0)--(i*u,10u);
label.bot(TEX("\$x_{"& decimal(i) &"}\$"),(i*u,0));
endfor;
draw (0,0) for i:=1 upto 10: ..(i*u,fun(i)) endfor;
endfig;
end;``````
Last updated on 28 Mar 2021
Published on 28 Mar 2021