3

Is there a way to use gnuplot for complicated calculations?

For
\pgfmathsetmacro{\x}{0.02} \pgfmathsetmacro{\y}{2*11000*(1 - 1.40576 - cos(\x) + sqrt(1.40576^2 - sin(\x)^2))}
for example I get 'Dimensions to large'.

enter image description here

% arara: pdflatex: {shell: yes}
\documentclass[margin=5mm, varwidth]{standalone}
\usepackage{siunitx}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\begin{document}
\pgfmathsetmacro{\x}{0.02}
%\pgfmathsetmacro{\y}{2*11000*(1 - 1.40576 - cos(\x) + sqrt(1.40576^2 - sin(\x)^2))}
Calculating works not: % \y


\begin{tikzpicture}[]
\newcommand\Curve[1]{2*11000*(1 - 1.40576 - cos(#1) + sqrt(1.40576^2 - sin(#1)^2))}
\begin{axis}[title=Graphing works:]
\addplot[blue,domain = {-0.07:0.07}] plot gnuplot[samples=500,id=curve]{\Curve{x}} node[anchor=east]{gnuplot: good};

\addplot[red,domain = {-0.07:0.07}, trig format plots=rad]{\Curve{x}} node[pos=0.5,anchor=north]{pgfplots: bad};
\end{axis}
\end{tikzpicture}
\end{document}
5

gnuplot is more for plotting but you could use expl3's floating point instead:

\documentclass{article}
\usepackage{xfp}
\begin{document}
\newcommand{\x}{0.02}
\edef\y{\fpeval{2*11000*(1 - 1.40576 - cos(\x) + sqrt(1.40576^2 - sin(\x)^2))}}
\typeout{y=\y}
\edef\y{\fpeval{2*11000*(1 - 1.40576 - cos(\x deg) + sqrt(1.40576^2 - sin(\x deg)^2))}}
\typeout{y=\y}
\end{document}

produces

y=1.270132770126
y=0.000386870374

(Note PGF uses degrees by default in trig functions)

  • Wouldn't we need \fpeval{2*11000*(1 - 1.40576 - cos(\x deg) + sqrt(1.40576^2 - sin(\x deg)^2))} to have the arguments of circular functions interpreted the same way as with pgfmath? (I get: 0.000386870374) – frougon Jun 22 at 9:13
  • @frougon oh you want mathematically correct results not just an error free tex run? So converntional:-) Yes thanks, I'll fix – David Carlisle Jun 22 at 9:18
  • Oh, no, rest assured: not me—but maybe cis? :-) – frougon Jun 22 at 9:20
  • @frougon better? – David Carlisle Jun 22 at 9:22
  • You now have the same result I got: so we are either both right or both wrong, that's all I can say. :-P (well, you gave two results, kind of cheating!) – frougon Jun 22 at 9:24
3

If I do things as the manuals suggest me to do, then there is no problem. In particular, you may want to

  1. switch on fpu to use it. Just loading pgfplots doesn't switch it on. In fact, you need to switch it off again before you start a tikzpicture.
  2. Use lualatex -shell-escape for the compilation.

Then the results are fully consistent.

\documentclass[margin=5mm, varwidth]{standalone}
\usepackage{siunitx}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\begin{document}
\pgfmathsetmacro{\x}{0.02}
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=sci}
\pgfmathsetmacro{\y}{2*11000*(1 - 1.40576 - cos(\x) + sqrt(1.40576^2 -
pow(sin(\x),2)))}
Calculating works:  \y
\pgfkeys{/pgf/fpu=false}


\begin{tikzpicture}[declare function={f(\x)=2*11000*(1 - 1.40576 - cos(\x) +
sqrt(1.40576^2 - sin(\x)^2));}]
\newcommand\Curve[1]{2*11000*(1 - 1.40576 - cos(#1) + sqrt(1.40576^2 - sin(#1)^2))}

\begin{axis}[title=Graphing works:]
\addplot[blue,domain = {-0.07:0.07}] plot
gnuplot[samples=500,id=curve]{\Curve{x}} node[anchor=east]{gnuplot: good};

\addplot[red,dashed,domain = {-0.07:0.07}, trig format plots=rad]{f(x)}
node[pos=0.5,anchor=north]{pgfplots: good};
\end{axis}
\end{tikzpicture}
\end{document}

enter image description here

Whether or not the result for \y is what you want or you need to add \pgfkeys{/pgf/trig format=rad} or something I don't know.

  • Seems to be good with fpu. But the value should be f(x)=1.27013 for x=0.02 or f(x)=0.000386 for x=0.02° I thought fpu does not always work either. gnuplot creates an auxiliary file gnuplot01.curve.table You would have to somehow make him do that for the calculated value; and then read the table value. – cis Jun 22 at 13:19
  • @cis fpu does "work" but you are right in that it is not very accurate for trigonometric functions and small values. And yes, gnuplot generates a table which gets read. Similarly, when you use lualatex, the computations are not done by TeX, so they are more accurate. – marmot Jun 22 at 13:27
1

R have not problems with these calculations nor plotting the result with enough points:

mwe0

\documentclass{article}
\begin{document}
<<echo=F,results='asis', fig.width=4,fig.height=4>>=
x = seq(-0.07,0.07,0.0001)
y=2*11000*(1 - 1.40576 - cos(x) + sqrt(1.40576^2 - sin(x)^2)) 
plot(x,y,type="l",lwd=3,col="blue")
@
\end{document}

OK, is the same parabola but not the same graph. Now with tikz look & feel:

mwe

\documentclass{article}
\begin{document}
<<echo=F,results='asis',dev="tikz",fig.width=4,fig.height=4>>=
x = seq(-0.07,0.07,0.0001)
y=2*11000*(1 - 1.40576 - cos(x) + sqrt(1.40576^2 - sin(x)^2)) 
plot(x*100,y,type="l",lwd=3,col="blue", 
xlab="$x \\times10^{-2}$", ylab="$y$", xlim=c(-8.5,8.5),  
xaxp  = c(-10,10,10), tck=0.02)
axis(side = 4, tck=0.02, labels = NA)
axis(side = 3, tck=0.02, at=seq(-8,8,2), labels = NA)
@
\end{document}
0

Something like that:

Short:

enter image description here

% arara: pdflatex: {shell: yes}
\documentclass[margin=5mm, varwidth]{standalone}
\usepackage{pgfplots, pgfplotstable}
\pgfplotsset{compat=1.16}
\newsavebox{\mycalc}
% See too: http://gnuplot.sourceforge.net/docs_4.2/node53.html  
\begin{document}


\newcommand\Function[3][fixed,precision=6]{%%%%%%%%%
\sbox{\mycalc}{%%
\begin{tikzpicture}[]
\begin{axis}[]
\addplot[blue,domain = {#3:#3+0.1}] plot gnuplot[id=mycalc]{#2};
%\addplot[blue,domain = {pi:2*pi}] plot gnuplot[id=mycalc]{5};
\end{axis}
\end{tikzpicture}
}%%%
%\usebox{\mycalc}
%
\pgfplotstableread[header=false]{\jobname.mycalc.table}\tempdata% 
%\pgfplotstabletypeset[string type]{\tempdata}
%
\pgfplotstablegetelem{0}{1}\of\tempdata
\pgfmathsetmacro\y{\pgfplotsretval}
\pgfmathprintnumber[#1]{\y}%
}%%%%%%%%%%%%%%%



\section{Easy}
$\sin(\frac\pi6) = \Function{sin(x)}{pi/6}$

\section{Difficult}
\newcommand\Curve[1]{2*11000*(1 - 1.40576 - cos(#1) + sqrt(1.40576^2 - sin(#1)^2))
}
\newcommand\curve[1]{2\cdot 11000\cdot \left(1 - 1.40576 - \cos(#1) + \sqrt{1.40576^2 - \sin(#1)^2}\right)}

Let $f(x) =\curve{x}$.
\pgfmathsetmacro\x{0.05}

$f(\x) = \Function{\Curve{x}}{\x}$
\end{document}

Long:

enter image description here

% arara: pdflatex: {shell: yes}
\documentclass[margin=5mm, varwidth]{standalone}
\usepackage{pgfplots, pgfplotstable}
\pgfplotsset{compat=1.16}

\newcommand\Curve[1]{2*11000*(1 - 1.40576 - cos(#1) + sqrt(1.40576^2 - sin(#1)^2))
}
\newcommand\curve[1]{2\cdot 11000\cdot \left(1 - 1.40576 - \cos(#1) + \sqrt{1.40576^2 - \sin(#1)^2}\right)}

\begin{document}
Let $f(x) =\curve{x}$.

\pgfmathsetmacro\x{0.05}
We need $f(\x)$

\newsavebox{\mycalc}
\sbox{\mycalc}{%%%%%%%%%%%%%%%%%
\begin{tikzpicture}[]
\begin{axis}[]
\addplot[blue,domain = {\x:\x+0.1}] plot gnuplot[id=mycalc]{\Curve{x}};
%\addplot[blue,domain = {pi:2*pi}] plot gnuplot[id=mycalc]{5};
\end{axis}
\end{tikzpicture}
}%%%%%%%%%%%%%%%%%%%%%%%
\section{Show graph - for Info}
\usebox{\mycalc}


\section{Show gnuplot-generated table - for Info}
\pgfplotstableread[header=false]{\jobname.mycalc.table}\tempdata 
\pgfplotstabletypeset[string type]{\tempdata}

\section{Read out value}
\pgfplotstablegetelem{0}{1}\of\tempdata
%\pgfkeys{/pgf/number format/.cd,sci}
%\pgfkeys{/pgf/number format/.cd,fixed,precision=6}
\pgfmathsetmacro\y{\pgfplotsretval}

$f(\x) = \pgfmathprintnumber[fixed,precision=6]{\y}$

$f(\x) = \pgfmathprintnumber[sci,precision=6]{\y}$

\end{document}

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.