8

Thanks for your help in advance:)

I have a problem with tikz calculating/printing the values of my function wrong.

The function is f(x) = (ax³+bx²+cx)*e^(dx) with a=-3.01718 b=11.8804 c=0.753323 d=-0.790569

The tikz graph looks very good from x=0 to x=11.2

The graph gets wrong from x > 11.4

You can compare the tikz graph to the graph from geogebra.

enter image description here

enter image description here

This is the code:

\documentclass[a4paper,11pt]{scrartcl}
\usepackage[ngerman]{babel}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}%[scale=0.5]
\draw[thin,color=gray,xstep=1,ystep=1, solid] (0,-3) grid (13,7);
\draw[->,line width=0.8mm] (0,0) -- (13,0);
\draw[->,line width=0.8mm] (0,-3) -- (0,7);
\foreach \x/\xtext in {1/1, 2/2, 3/3, 4/4, 5/5, 6/6, 7/7, 8/8, 9/9, 10/10, 11/11, 12/12}
\draw[shift={(\x,0)}] (0pt,2pt) -- (0pt,-2pt) node[below] {$\xtext$};
\foreach \y/\ytext in {-2/-2, -1/-1, 0/0, 1/1, 2/2, 3/3, 4/4, 5/5, 6/6}
\draw[shift={(0,\y)}] (2pt,0pt) -- (-2pt,0pt) node[left] {$\ytext$};

\draw[line width=0.4mm, domain=0:12.8,smooth,variable=\x,black] plot ({\x},{((-3.017180* 
(\x)^3+11.88040*(\x)^2+0.753323*(\x))*e^(-0.790569*(\x))) });
\end{tikzpicture}

\end{document}

Thanks for your help!

  • Related – user108724 Sep 18 at 15:59
15

This is caused by how the pgf math function exp is implemented. A simplified example:

\documentclass{article}
\usepackage{pgfmath, pgffor}

\begin{document}
\foreach \i in {8.9, 9.0, 9.1} {
  \pgfmathparse{exp(-\i)}exp(-\i) = \pgfmathresult\par
}
\end{document}

The output is

exp(-8.9) = 0.00012
exp(-9.0) = 0.00012
exp(-9.1) = 0.00002  % <<< see the jump from 1.2e-4 to 2e-5

The relation between OP's example and mine is that, when x ~= 11.384, -0.790569*(\x) is near -9, and e^x is equivalent to exp(x).

The current implementation of exp(x) simply returns 1/65536 ~= 0.00002 when x < -9 (introduced by commit 29a3525e6f5f in 2008, from pgf 2.10), which causes the jumping value near -9.

Using a smaller jumping point instead of -9 will trigger error dimension too large more often, hence is not a neat solution. For example, with -10, plotting OP's function will raise dimension too large near x = 12.3.

Using some floating-point calculation utility is better. The latest code base of tikz-pgf has introduced a new key /pgf/fpu/install only={<math function list>} which can be used to locally switch implementations of specific math functions to their fpu version.

The following example makes use of install only key, and will generate the same output as in daleif's answer. I guess pgfplots uses similar tricks to perform floating-point calculations when plotting.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fpu}

\begin{document}

\begin{tikzpicture}[declare function={
    f(\x) = (-3.017180*(\x)^3+11.88040*(\x)^2+0.753323*(\x))*e^(-0.790569*(\x));
  }]
  \draw[thin,color=gray]
    (0,-3) grid (13,7);
  \draw[->,line width=0.8mm]
    (0,0) -- (13,0)
    (0,-3) -- (0,7);
  \foreach \x in {1, 2, ..., 12}
    \draw[shift={(\x,0)}] (0pt,2pt) -- (0pt,-2pt) node[below] {$\x$};
  \foreach \y in {-2, -1, ..., 6}
    \draw[shift={(0,\y)}] (2pt,0pt) -- (-2pt,0pt) node[left] {$\y$};
  
  % use "/pgf/fpu/install only={exp}"
  \draw[line width=0.4mm, domain=0:12.8, smooth, /pgf/fpu/install only={exp}]
    plot (\x, {f(\x)});
\end{tikzpicture}
\end{document}

Other choices

See pgfmanual, v3.1.5b,

  • sec. 22.4 Plotting Points Read From an External File and
  • sec. 22.6 Plotting a Function Using Gnuplot.
| improve this answer | |
  • Thank you very much! Now i got a better understanding of whats causing the issue. – schreibelehmann Sep 17 at 18:52
  • Next question/problem is, that the use of "/pgf/fpu/install only={exp}" doesnt work for me. I get the error "/pgf/fpu/install only={exp}" I use texlive-pgf 3.1.5 (complete: 2020.176.3.1.5bsvn54512-41.2 on openSUSE tumbleweed) – schreibelehmann Sep 17 at 18:54
  • 1
    @schreibelehmann Try github.com/pgf-tikz/pgf, the official repo. I've tested, that manually applying commit 494bd677709b works. – muzimuzhi Z Sep 17 at 20:22
  • - Thanks for the clarification. I'm not good at programming and github stuff, thatswhy i just copied manually the addition lines from the patch you mentioned into my "/usr/share/texmf/tex/generic/pgf/libraries/pgflibraryfpu.code.tex" file. It works! Thanks alot! When there is a texlive pfg-package update, shall i undo the manually changes? (Info: i have a safe-copy of the old file) – schreibelehmann Sep 18 at 11:46
  • @schreibelehmann I guess the change will just be overwritten when updating. – muzimuzhi Z Sep 18 at 14:01
12

No idea why this particular plot looks like this, but I would never plot a function by hand like this. I'd use pgfplots where it looks like this

\documentclass[a4paper,11pt,border=10pt,]{standalone}
\usepackage{tikz,pgfplots}
\begin{document}
\begin{tikzpicture}%[scale=0.5]
\begin{axis}[
  width=13cm,
  ymin=-2.1,
  ymax=5.5,
  domain=0:12.8,
  no marks,
  axis x line=center,
  axis y line=center,
  ]

  \addplot[smooth] {((-3.017180*(\x)^3+11.88040*(\x)^2+0.753323*(\x))*e^(-0.790569*(\x)))};
  
\end{axis}

\end{tikzpicture}

\end{document}

(pgfplots has a massive amount of configuration options)

And the result is:

enter image description here

| improve this answer | |
  • Thank you very much for your suggestion. I'm still learning how to use the \begin[axis] and \addplot yet. Thatswhy i did it the way postet earlier :) – schreibelehmann Sep 17 at 18:58

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.