When I define a mathematical function for plotting in pgfplots or pstricks I usually to it in the following way:

\def\f(#1){(#1)^3 + 3*exp(#1)}

just as suggested by Jake in his answer to a question about how to define a function consistently for plotting and computations in pgfplots with and without gnuplot.

However is it possible to define say \defF such I can write:

\defF\f(x){x^3 + 3*exp(x)}

which should be equivalent to the first definition using \def and #1 above?


Short answer: are you sure you gain in code readability?

Long answer: yes, it can be done.


 {% #1 = function name (a macro), #2 = variable, #3 = formula
  \tl_set:Nn \l_tmpa_tl { #3 }
  \regex_replace_all:nnN { \b#2\b } { \cP\#1 } \l_tmpa_tl
  \cs_gset:cV { function_inner_\cs_to_str:N #1 :n } \l_tmpa_tl
  \cs_new:Npn #1 ( ##1 )
    \use:c { function_inner_\cs_to_str:N #1 :n } { ##1 }
\cs_generate_variant:Nn \cs_gset:Nn { cV }

\cs_set_eq:NN \eval \fp_eval:n

\functiondef\f(x){x^3 + 3*exp(x)}




Here I use \fp_eval:n, adapt it to PGF.

enter image description here

If I do

echo '42^3+3*e(42)' | bc -l

I get


The accuracy depends, of course, on the number crunching engine.


The replacement text is stored in a sequence; every appearance of x (the stated variable name, more generally) surrounded by word boundaries is replaced by #1. This token list is then passed to \cs_gset:cV that builds a regular macro named \function_inner_f:n (the actual name is built from the first argument to \functiondef) and then the macro \f with the argument surrounded by parentheses is defined to use \function_inner_f:n.

  • Great, thanks a lot. And yes I think that the code gains readability. In some cases I can also use directly copy and paste without doing a (admittedly simple) search and replace step (x -> #1).
    – student
    Jan 1 '15 at 11:26
\def\f(x){x^3 + 3*Euler^x}



enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.