Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Is there a way to easily compute the erf function (or the cumulative distribution function of the normal law) in LaTeX?

Currently, I use pgf to make computation, but I did not find a way to compute erf using pgf.

I would be happy to use any package that is available to compute erf, or any custom solution to compute that function.

share|improve this question
    
These references might help you: How to Draw CDF of normal distribution in Tikz and Draw a bivariate normal distribution in TikZ. Actually, there are other useful answers (I've read another interesting one by Jake, but I can't find it now) on the site: perhaps a deeper search is worth. –  Claudio Fiandrino Apr 7 '13 at 18:50
    
I don't want to draw the function, I want to compute and typeset the values. I read that link, but it's not really useful for what I need. Thanks –  Xoff Apr 7 '13 at 18:54
1  
@Xoff You can create a pgfmath function very easily with the Taylor expression of the erf function. The precision won't be that good anyway as TeX is not meant for math. (Although certain floating point packages/libraries may help here to a certain degree.) –  Qrrbrbirlbel Apr 7 '13 at 19:02
    
Sure, I can do it myself. But as it's a very common function in some mathematical area, I hope someone already did something good to compute it. –  Xoff Apr 7 '13 at 19:33

5 Answers 5

up vote 9 down vote accepted

For precise values, I recommend externalizing the calculation, here gnuplot is used.

Code (needs --shell-escape enabled)

\documentclass{article}
\usepackage{amsmath,pgfmath,pgffor}
\makeatletter
\def\qrr@split@result#1 #2\@qrr@split@result{\edef\erfInput{#1}\edef\erfResult{#2}}
\newcommand*{\gnuplotErf}[2][\jobname.eval]{%
    \immediate\write18{gnuplot -e "set print '#1'; print #2, erf(#2);"}%
    \everyeof{\noexpand}
    \edef\qrr@temp{\@@input #1 }%
    \expandafter\qrr@split@result\qrr@temp\@qrr@split@result
}
\makeatother
\DeclareMathOperator{\erf}{erf}
\begin{document}
\foreach \x in {-50,...,50}{%
\pgfmathparse{\x/50}%
\gnuplotErf{\x/50.}%
$ x = \pgfmathresult = \erfInput, \erf(x) = \erfResult$\par
}
\end{document}

Output

enter image description here

share|improve this answer
3  
Here is a comparison of cjorssen’s (good!) answer and gnuplot’s values –  Qrrbrbirlbel Apr 7 '13 at 20:36
    
I get a strange error: runsystem(gnuplot -e "set print 'erf.eval'; print -50/50., erf(-50/50.);")...quotation error in system command (tl2012, debian)? Never had it before. –  cjorssen Apr 7 '13 at 20:55
    
It works nicely for me –  Xoff Apr 7 '13 at 21:20
2  
It's fixed in the CVS version but pgfmath,pgffor is not enough to compile in v2.10 official release. One needs to load pgf,pgffor to get everything otherwise pgfkeys etc. don't work. There was a dependency leak which was fixed some time ago in the CVS version. –  percusse Apr 7 '13 at 21:31

Based on this answer.

\documentclass{standalone}
\usepackage{tikz}
\makeatletter
\pgfmathdeclarefunction{erf}{1}{%
  \begingroup
    \pgfmathparse{#1 > 0 ? 1 : -1}%
    \edef\sign{\pgfmathresult}%
    \pgfmathparse{abs(#1)}%
    \edef\x{\pgfmathresult}%
    \pgfmathparse{1/(1+0.3275911*\x)}%
    \edef\t{\pgfmathresult}%
    \pgfmathparse{%
      1 - (((((1.061405429*\t -1.453152027)*\t) + 1.421413741)*\t 
      -0.284496736)*\t + 0.254829592)*\t*exp(-(\x*\x))}%
    \edef\y{\pgfmathresult}%
    \pgfmathparse{(\sign)*\y}%
    \pgfmath@smuggleone\pgfmathresult%
  \endgroup
}
\makeatother
\begin{document}
\begin{tikzpicture}[yscale = 3]
  \draw[very thick,->] (-5,0) -- node[at end,below] {$x$}(5,0);
  \draw[very thick,->] (0,-1) -- node[below left] {$0$} node[at end,
  left] {$erf(x)$} (0,1);
  \draw[red,thick] plot[domain=-5:5,samples=200] (\x,{erf(\x)});
\end{tikzpicture}
\end{document}

enter image description here

share|improve this answer
    
I up this answer, thank you. I was hoping something more precise was implemented. –  Xoff Apr 7 '13 at 21:21
    
@Xoff You can also use the gnuplot engine to plot in TikZ/pgfplots. –  Qrrbrbirlbel Apr 8 '13 at 21:31
2  
@Xoff That formula (7.1.26. in A Handbook of Mathematical Functions by Abramowitz and Stegun) has an error bounded by $1.5 \times 10^{-7}$. I don't think it's possible to get closer in TeX. –  Matthew Leingang Apr 17 '13 at 16:00
    
Thanks for the intel, it's good to know ! –  Xoff Apr 17 '13 at 18:32

Using the same approximation idea as cjorssen (I tried the Taylor series as Qrrbrbirlbel suggested but it's pretty hopeless to get a decent approximation this way) I rewrote the function without using low-level PGF. Because we have so many 2D plots here already, I'll just use my 3D plot that I had already.

\documentclass{standalone}
\usepackage{pgfplots}
\usepackage{tikz}
\pgfplotsset{
colormap={bluewhite}{ color(0cm)=(rgb:red,18;green,64;blue,171); color(1cm)=(white)}
}
\begin{document}
\begin{tikzpicture}[
    declare function={erf(\x)=%
      (1+(e^(-(\x*\x))*(-265.057+abs(\x)*(-135.065+abs(\x)%
      *(-59.646+(-6.84727-0.777889*abs(\x))*abs(\x)))))%
      /(3.05259+abs(\x))^5)*(\x>0?1:-1);},
    declare function={erf2(\x,\y)=erf(\x)+erf(\y);}
]
\begin{axis}[
    small,
    colormap name=bluewhite,
    width=\textwidth,
    enlargelimits=false,
    grid=major,
    domain=-3:3,
    y domain=-3:3,
    samples=33,
    unit vector ratio*=1 1 1,
    view={20}{20},
    colorbar,
    colorbar style={
        at={(1,-.15)},
        anchor=south west,
        height=0.25*\pgfkeysvalueof{/pgfplots/parent axis height},
    }
]
\addplot3 [surf,shader=faceted] {erf2(x,y)};
\end{axis}
\end{tikzpicture}
\end{document}

3D plot of erf(x)+erf(y)

The approximation has a maximum error of 1.5·10-7 (source).

Thanks to Jake for spotting and fixing the wrong syntax I first had in this code.

share|improve this answer

A little late, but here's a solution using the sagetex package, which gives you the power of the (free) computer algebra system known as Sage. Sage has an error function command which, according to the documentation is 1-erf. This code

\documentclass{article}
\usepackage{sagetex}
\begin{document}
\pagestyle{empty}
Sage has an error function command that's equal to $1-\mbox{erf}$. Here's     $\sage{error_fcn(2)}$ and 
$\sage{1-error_fcn(2)}$. There is an erf command but it doesn't seem to be   working properly 
in my older version of Sage. The formatting in Sage goes like this:   $\sage{n(error_fcn(2),digits=6)}$ 
and $\sage{n((1-error_fcn(2)),digits=11)}$. 
\begin{sagesilent}
g(x)=erf(x)
q=plot(g,x,-3,3,color='red')
\end{sagesilent}

This is a plot of $\mbox{erf}(x)$.
\begin{center}
\sageplot[scale=.35]{q}
\end{center}
\end{document}

creates this output: enter image description here

share|improve this answer
    
I did not find a way to get this package with texlive. Did I miss something ? –  Xoff Apr 10 '13 at 16:00
    
You need to install Sage on your computer. The download link is here. Once you installed you just need to copy sagetex.sty to the place where you latex your document: see here and here for more details. Sagetex and TexLive mentioned at 2nd "here" link. –  DJP Apr 10 '13 at 22:51

Error function erf(x) computation and figure anatomy (axes,legends and labels) have been rendered in three approaches.

  1. Fully gnuplot
  2. pgfplots invokes gnuplot
  3. Fully Matlab

Already there are good answers for example by Qrrbrbirlbel and cjorssen, both exploit pgfmath at macro level.

1. Fully gnuplot

Error function erf(x) computation in gnuplot with axes, legends and labels rendered in gnuplot epslatex terminal. The gnuplot terminal output is embedded automatically with gnuplottex package. terminal=pdf does not render Math labels hence epslatex terminal was used.

\documentclass[preview=true,12pt]{standalone}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{gnuplottex}
\begin{document} 
\begin{gnuplot}[terminal=epslatex,terminaloptions=color]
  set grid
  set size square
  set key left 
  set title 'Error function in gnuplot  $ erf(x) = \frac{2}{\sqrt{\pi}} \int_{0}^{x}e^{-t^{2}}\, dt$'
  set samples 50
  set xlabel "$x$"
  set ylabel "$erf(x)$"
  plot [-3:3] [-1:1] erf(x) title 'gnuplot' linetype 1 linewidth 3
\end{gnuplot}
\end{document}

1) gnuplot output figure enter image description here

2. pgfplots invokes gnuplot

Error function erf(x) computation in gnuplot invoked by pgfplots and axes, legends, labels are rendered by pgfplots

\documentclass[preview=true,12pt]{standalone}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{pgfplots}
\pgfplotsset{compat=1.8}
\begin{document} 
\begin{tikzpicture}
\begin{axis}[xlabel=$x$,ylabel=$erf(x)$,title= {Error function in pgfplots $erf(x)=\frac{2}{\sqrt{\pi}}\int_{0}^{x}e^{-t^{2}}\, dt$},legend style={draw=none},legend pos=north west,grid=major,enlargelimits=false]
\addplot [domain=-3:3,samples=50,red,no markers] gnuplot[id=erf]{erf(x)};
% Note: \addplot function { gnuplot code } is alias for \addplot gnuplot { gnuplot code };
\legend{pgfplots-gnuplot}
\end{axis}
\end{tikzpicture}
\end{document}

2. pgfplots(gnuplot backend)output figure

enter image description here

3) Fully Matlab

Error function $erf(x)$ computation in Matlab with axes,legends,labels rendered using matlabfrag(psfrag tag based) and mlf2pdf functions.

Note: Fonts are frozen in PDF figure unlike the above approaches, but can be changed in mlf2pdf.m before generating them.

*erf(x) Matlab Script using mlf2pdf(matlabfrag as backend) to generate pdf *

clear all
clc
% Plotting section
    set(0,'DefaultFigureColor','w','DefaultTextFontName','Times','DefaultTextFontSize',12,'DefaultTextFontWeight','bold','DefaultAxesFontName','Times','DefaultAxesFontSize',12,'DefaultAxesFontWeight','bold','DefaultLineLineWidth',2,'DefaultLineMarkerSize',8);

% x and y data
x=linspace(-3,3,50);
y=erf(x);

figure(1);plot(x,y,'r');
grid on
axis([-3 3 -1 1]);
xlabel('$x$','Interpreter','none');
ylabel('$erf(x)$','Interpreter','none');
legend('Matlab');legend('boxoff');
title('Error function in Matlab $erf(x)=\frac{2}{\sqrt{\pi}}\int_{0}^{x}e^{-t^{2}}\, dt$','Interpreter','none');
mlf2pdf(gcf,'error-func-fig');

3. Output Figure enter image description here

gnuplot 4.4,pgfplots 1.8 and pdflatex -shell-escape engine were used.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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