10

I want to plot the graph of the function given by:

f(x)=abs(x - x^3/6 - sin(x)) for -1<= x <=1

but a noise (near x-axis) curve is obtained: The code is the following:

\documentclass[11pt,border=1mm]{standalone}
\usepackage[portuguese, shorthands=off]{babel} 
\usepackage[utf8]{inputenc}
\usepackage{tikz,pgfplots}

\begin{document}

\begin{tikzpicture}
\begin{axis}[
xmin = -1, 
xmax = 1,
width = 10cm]
\addplot[domain = -1:1,samples = 1000,smooth,color=blue]
{abs(x-x^3/6-sin(deg(x)))};
\end{axis}
\end{tikzpicture}

\end{document}

and the output produced is the following: enter image description here

How can I fix this?

4
8

There was a similar question not so far in the past. If was already guessed the root cause of the "noise" is TeXs calculation engine. So the solution is to use another calculation engine. Here I show the comparison of TeX and Lua. In my answer to the similar question you can also find the engines gnuplot and l3/xfp.

% used PGFPlots v1.18.1
\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
    % use this `compat` level or higher to make use of the Lua calculation engine
    \pgfplotsset{compat=1.12}
\begin{document}
\begin{tikzpicture}
    \begin{axis}[
        cycle multiindex* list={
            color\nextlist
            [1 of]mark list\nextlist
        },
        xmin=-1,
        xmax=1,
        domain=-1:1,
        samples=51,
        smooth,
%        no markers,
        mark size=1pt,
        trig format=rad,
    ]
        % using TeX as calculation engine
        \addplot+ [thick] {abs(\x-\x^3/6-sin(\x))};
        % using Lua as calculation engine
        \addplot          {abs(x-x^3/6-sin(x))};
    \end{axis}
\end{tikzpicture}
\end{document}

image showing the result of above code

4
  • do I need to use LuaLaTeX to fully gain the advantage of the LUA calculation engine or is the same result possible if I use PDFLaTeX to compile this document?
    – Lukas
    Sep 25 at 7:38
  • 2
    @Lukas, (of course) you need to compile with LuaLaTeX to make use of Lua stuff ... ;) Sep 25 at 18:19
  • I was just a little puzzled because it compiled with pdflatex without an error :D thanks for the information!
    – Lukas
    Sep 25 at 18:28
  • 1
    @Lukas, yes it does. If you want to know why, see the comments in my quoted answer. Sep 26 at 5:01
7

As others have explained, you're relying on pgfmath to do calculations and that is prone to round off errors. It's great for the sort of calculations that come up for most people but you're working with a more complicated function. The answer then is to use a more appropriate tool, a computer algebra system, to do the calculation. This is possible with the sagetex package, found here on CTAN. This package lets you farm out the calculations to open source CAS Sage instead of using pgfmath. The result will be accurate calculations which can be used in your plot.

\documentclass[11pt,border=1mm]{standalone}
\usepackage{sagetex}
\usepackage[usenames,dvipsnames]{xcolor}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\begin{document}
\begin{sagesilent}
LowerX = -1
UpperX = 1
LowerY = -.001
UpperY = .009
step = .001
t = var('t')
g(x)= abs(x-x^3/6-sin(x))

x_coords = [t for t in srange(LowerX,UpperX,step)]
y_coords = [g(t).n(digits=6) for t in srange(LowerX,UpperX,step)]

output = r""
output += r"\begin{tikzpicture}[scale=1.0]"
output += r"\begin{axis}[xmin=%f,xmax=%f,ymin= %f,ymax=%f,width=10cm]"%(LowerX,UpperX,LowerY, UpperY)
output += r"\addplot[thin, blue, unbounded coords=jump] coordinates {"
for i in range(0,len(x_coords)-1):
    if (y_coords[i])<LowerY or (y_coords[i])>UpperY:
        output += r"(%f , inf) "%(x_coords[i])
    else:
        output += r"(%f , %f) "%(x_coords[i],y_coords[i])
output += r"};"
output += r"\end{axis}"
output += r"\end{tikzpicture}"
\end{sagesilent}
\sagestr{output}
\end{document}

The code, running in Cocalc, is shown below: enter image description here

Sage is not part of your LaTeX distribution so this will not work on your machine unless you either 1. download the program to your machine and get it to work with your LaTeX distribution (which can be troublesome) or 2. open a free Cocalc account which gives you access to Sage over the internet.

Sage also gives you access to Python which you can then use as well. See, for example, how the Cantor function is plotted using sagetex. Search this site for sagetex and you will see how it can be used for more complex mathematical problems, such as finding a transpose of a matrix.

2
  • May I know where I can read more about the usage of r""?
    – Diaa
    Nov 22 at 7:51
  • This is what is called a raw string in Python if you are searching. It is important when the strings you have contain certain characters, such as a backslash. An explanation can be found here. "Hi\t everybody" will put a tab between Hi and everybody but r"Hi\t everybody" will print out just like it looks.
    – DJP
    Nov 22 at 22:12
7

Update:

One of difficult problems with beginner is to compile any single Asymptote code(s), thus, I have shared a way which I used beside http://asymptote.ualberta.ca/, here is it.

While waiting for a TikZ/PGF answer, see a runnable code with Asymptote.

One of features of Asymptote:

...

inspired by MetaPost, with a much cleaner, powerful C++-like programming syntax and IEEE floating-point numerics;

...

import graph;

size(350,300,false); // The boolean "false" is important.

real f(real x){ return abs(x-x^3/6-sin(x));}
guide F=graph(f,-1,1,500);
// domain -1,1
// samples 500

draw(F,1bp+blue);
limits((-1,-1e-3),(1,9*1e-3)); // See page 113 in the documentation
xaxis("$x$",BottomTop,LeftTicks(Size=4,Ticks=uniform(-1,1,10)));
yaxis("$y$",LeftRight,RightTicks(ticklabel=new string(real x){ return 
                                 format("%.3f",1e+3*x);},
                                 Size=4,Ticks=1e-3*uniform(0,8,4)));
labelx("$.10^{-3}$",(-1,9*1e-3),N+0.7E); // See page 104 in the documentation

enter image description here

1
  • Nice! it can be an example on the Asymptote gallery on 2D graphs
    – Black Mild
    Sep 25 at 19:25
5

Looks like tikz has some numerical limitations, here. E.g. increasing the samples gives even more errors, like shown below, while decreasing is better, but not what you want.

10-fold sample size

However, if you switch to PSTricks, numerics seems to be better. Here is some starting code, with remarks below the next drawing.

\documentclass[11pt,border=1mm]{article}
%\documentclass[11pt,border=1mm]{standalone}
%\usepackage[portuguese, shorthands=off]{babel} 
\usepackage[utf8]{inputenc}
%\usepackage{tikz,pgfplots}
\usepackage{pst-plot}

\begin{document}
    \begin{pspicture}
        \psplot{-1}{1}{x 3 exp neg 6 div x add x RadtoDeg sin neg add abs 1000 mul}
    \end{pspicture}
\end{document}

Collage from Acrobat reader:

Acrobat result

REMARKS:

  1. For simplicity I left out grid or axes. Not too difficult to add, but too difficult for me right now ;-)

  2. f(x) looks a bit odd ... think of entering your equation term by term on an old HP-calculator in so called polish notation (values operation => result, repeat). For simplification I multiplied by 1000 at the end.

  3. During compile make sure you advise your Latex-compiler to go via dvips ... else it won't create a pdf.

  4. The generated .ps and .pdf are vector graphics, i.e. with less trouble from the numerical side, also during display. If the line looks blurred, increase the lines linewidth during plotting: it's an artifact from your computers display system.

  5. If you need more samples, a simple-stupid way is to let x run from -10 to +10 AND divide it by 10 inside \psplot. There may be better ways to do it.

  6. In your final document you could use \includegraphics to show any graphic, which you created as a separate .pdf with tikz OR PSTricks.

2

This (too long for a comment) is an auxiliary for the above Asymptote answer. The question is interesting in the sense that the options [smooth], [samples] of the plot command in TikZ do not work as expected due to computation limit of pgfmath. So Asymptote is one of suitable choices.

The following illustrates the sine function, the 3rd-order Taylor polynomial, and the 3rd-order Taylor remainder. Thus, visually the approximation T_3(x) of sin(x) is only good in a vicinity of the origin where the remainder is almost horizontal.

enter image description here

// http://asymptote.ualberta.ca/
unitsize(1cm);
size(8cm);
import graph;
usepackage("amsmath");
pen p=gray+opacity(.5);
draw((-2pi-1,0)--(2pi+1,0),p);
draw((0,-4)--(0,5),p);

// graph of sin(.)
path F=graph(sin,-2pi,2pi);
draw(Label("$y=\sin x$",EndPoint,N),F,blue);

// graph of the 3rd-order Taylor polynomial
real T3(real x){ return (x-x^3/6);}
guide G=graph(T3,-1.1pi,1.1pi);
draw(Label(scale(.8)*"$T_3(x)=x-\dfrac{x^3}{6}$",EndPoint,E),G,darkcyan);

// graph of the 3rd-order Taylor remainder
real r(real x){ return abs(x-x^3/6-sin(x));}
guide R=graph(r,-1.15pi,1.15pi,500);
draw(Label(scale(.8)*"$r_3(x)=\left|x-\dfrac{x^3}{6}-\sin x\right|$",BeginPoint),R,magenta);

shipout(bbox(5mm,invisible));

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