# Is plotting exponential graphs a known source of bugs in TikZ?

I want to plot $y = 2^x$ over a small domain. Unfortunately, even though tikz (v 2.1) seems to be able to calculate 2^{negative numbers} it is not plotting them correctly.

My minimal example is:

\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
The value of $2^{-1}$ is \pgfmathparse{pow(2,-1)}\pgfmathresult.
\begin{tikzpicture}
\draw[thick,->] (-2,0) -- (2,0) node[right]{$x$};
\draw[thick,->] (0,0) -- (0,5) node[above]{$y$};
\draw[blue,domain=-2:2] plot (\x,{exp(ln(2)*\x)});
\draw[red,domain=-2:2] plot (\x,{pow(2,\x)});
\end{tikzpicture}
\end{document}


The red and blue graphs should be identical, and they are for the very first point (x = -2) and all the non-negative values, but there seems to be some problem with the plotting algorithm that means there is a bizarre kink to make the red graph almost symmetrical.

Is this a known problem, and if so, has it been fixed in later versions of tikz?

-
I had done a similar diagram and it ran perfectly with TexLive2009 but when I changed to TeXLive2011 it gave output like yours. Your code works with TeXLive 2009 also. Sounds like a bug; I ended doing the diagram with PS Tricks (pst-plot). –  DJP Oct 17 '11 at 2:59
Plotting this with pgfplots works fine, which is probably a more convenient way of plotting functions than using "raw" TikZ. –  Jake Oct 17 '11 at 5:40
It's good to know that it works on pgfplots, but I'd prefer not to go with that workaround for the moment because the graph in question is part of something bigger that I've built on top of TikZ, so I'd like to make sure the underlying package is rock solid. –  bryn Oct 17 '11 at 9:10

Yes, as Leo Liu said, this is fixed in the CVS version. The change was made in revision 1.5 of pgfmathfunctions.basic.code.tex.

If you don't want to install the CVS version, you could also just include the new version of the offending exp function by including the following code in your preamble:

% fixed exp function.
%
\makeatletter
\let\pgfmath@function@exp\relax % undefine old exp function
\pgfmathdeclarefunction{exp}{1}{%
\begingroup
\pgfmath@xc=#1pt\relax
\pgfmath@yc=#1pt\relax
\ifdim\pgfmath@xc<-9pt
\pgfmath@x=1sp\relax
\else
\ifdim\pgfmath@xc<0pt
\pgfmath@xc=-\pgfmath@xc
\fi
\pgfmath@x=1pt\relax
\pgfmath@xa=1pt\relax
\pgfmath@xb=\pgfmath@x
\pgfmathloop%
\divide\pgfmath@xa by\pgfmathcounter
\pgfmath@xa=\pgfmath@tonumber\pgfmath@xc\pgfmath@xa%
\ifdim\pgfmath@x=\pgfmath@xb
\else
\pgfmath@xb=\pgfmath@x
\repeatpgfmathloop%
\ifdim\pgfmath@yc<0pt
\pgfmathreciprocal@{\pgfmath@tonumber\pgfmath@x}%
\pgfmath@x=\pgfmathresult pt\relax
\fi
\fi
\pgfmath@returnone\pgfmath@x%
\endgroup
}
\makeatother


Alternatively, using pgfplots for plotting the function works flawlessly out of the box.

-
I'm a bit surprised about this because the exp function is actually the one that is exhibiting the correct behaviour, whereas the pow function is doing the wrong thing within a plot command. I'm not sure why pow(a,b) isn't just defined in terms of exp anyway, and I find it even more bizarre that the pow(...,...) would work within a pgfmathparse but not within a plot. –  bryn Oct 17 '11 at 9:12
@bryn: The pow function does use the exp function internally, but only for non-integer values. If you try \pgfmathparse{pow(2,-0.5)}\pgfmathresult you'll get the same (wrong) result, 1.41, which is the same as 2^0.5. You can also see what happens when you plot \draw[red,domain=-2:2,samples=9] plot (\x,{pow(2,\x)});: Some of the samples are integers, and the function evaluates fine there. The problem arises because the minus sign is lost when pow calls exp (an expansion problem). You could also fix the problem by changing some code in the pow function, but this way is cleaner. –  Jake Oct 17 '11 at 11:50
I use TeX Live 2011 with CVS version of pgf package. The result is OK. Thus I think the bug has been fixed.
See tlcontrib to get the CVS version of pgf in TeX Live.
And for MiKTeX, you may go to sourceforge to check out latest pgf.