15

I'am using a macro from here (thanks to Schrödinger's cat). See my MWE:

\documentclass{scrartcl}
\usepackage{tikz}
\usetikzlibrary{fpu}
\newcommand\pgfmathparseFPU[1]{
                               \begingroup
                                 \pgfkeys{
                                          /pgf/fpu,
                                          /pgf/fpu/output format = fixed
                                         }
                                 \pgfmathparse{#1}
                                 \pgfmathsmuggle
                                 \pgfmathresult
                               \endgroup}

\begin{document}

  %data values:
  \def\UABmValues{{14.9, 15.8, 17.7, 18.3, 19, 20, 21.1, 22.2, 24.3, 26.9, 30.1}}

  %prints the result to the console:
  \foreach[count = \i from 0] \k in {30, 35, ..., 80}
    {
     \pgfmathsetmacro{\UABmValues}{\UABmValues[\i]}
     \pgfmathparseFPU{-25500 / (\UABmValues / 1000 - 255 / 52) - 5200 - 3.0897 / 8 * \k}\i, \pgfmathresult\\
    }

\end{document}

Gives:

  1. 4.414001000000000
  2. 3.483002000000000
  3. 3.652002000000000
  4. 2.221002000000000
  5. 0.990002
  6. 0.159003
  7. -0.571997
  8. -1.302997000000000
  9. -1.033997000000000
  10. -0.064996
  11. 1.304004000000000

When I do the same, let say, with MATLAB:

    UABmValues = [14.9 15.8 17.7 18.3 19 20 21.1 22.2 24.3 26.9 30.1];
    R = 30 : 5 : 80;

    %prints the result to the console:
    for j = 1 : 11

      result = -25500 / (UABmValues(j) / 1000 - 255 / 52) - 5200 - 3.0897 / 8 * R(j);
      fprintf('j=%d, ', j)
      fprintf('%d.\n', result)

    end

Than I get following:

  1. 4.261621e+00.
  2. 3.290914e+00.
  3. 3.388431e+00.
  4. 2.098301e+00.
  5. 9.151911e-01.
  6. 5.300458e-02.
  7. -7.017887e-01.
  8. -1.456052e+00.
  9. -1.139024e+00.
  10. -2.840543e-01.
  11. 1.217927e+00.

The difference is huge.

Why is it so? Any suggestions how to solve it with fpu, if at least possible?

Thank you for your help and effort in advance!

4
  • 7
    The PGF FPU uses TeX \dimen registers for calculations, so it has the same accuracy restrictions. The smallest representable difference in a TeX \dimen is 1sp, which is 0.00002pt (try \the\dimexpr1sp\relax). If you need more accuracy, try the LaTeX3 FPU (loaded by the xfp package). Dec 26 '19 at 12:32
  • 1
    @PhelypeOleinik fp gives good results ... but I agree with you xfp seems to be the good way. Perhaps lua is the better way ? Dec 26 '19 at 13:15
  • 5
    @AlainMatthes Yes, fp has a higher accuracy than the LaTeX3 FPU. (The latter conforms to the IEEE-754 standard, accurate to 16 significant digits or so). But xfp (and Lua, for that matter) is fully expandable, while fp is not. I'm not sure about Lua's accuracy. But my job description is to advertise expl3, so I had to suggest that ;-) Dec 26 '19 at 13:19
  • 1
    @PhelypeOleinik I agree with you xfp is fully expandable. I use fp because it was the only solution several years ago.I think you have wit lua IEEE 754 double precision floating point Dec 26 '19 at 14:42
20

The PGF floating point module is inaccurate, as it uses TeX arithmetic, so it doesn't go beyond five decimal digits. It is not meant as an all-purpose floating point arithmetic tool, but just to do typesetting.

Use xfp.

\documentclass{article}
\usepackage{tikz}
\usepackage{xfp}

\begin{document}

%data values:
\def\UABmValues{{14.9, 15.8, 17.7, 18.3, 19, 20, 21.1, 22.2, 24.3, 26.9, 30.1}}

%prints the result to the console:
\foreach[count = \i from 0] \k in {30, 35, ..., 80}
  {
   \pgfmathsetmacro{\UABmValues}{\UABmValues[\i]}
   \i, $\fpeval{-25500 / (\UABmValues / 1000 - 255 / 52) - 5200 - 3.0897 / 8 * \k}$\par
  }

\end{document}

enter image description here

1
  • 1
    This is the first I've heard of the xfp package. Are there any known side effects (for instance, speed)? Dec 27 '19 at 19:57
13

You can try fp, xfp (see egreg's answer) or lua

1) update : version with lua

% !TEX TS-program = lualatex

\documentclass{scrartcl}
\usepackage{pgffor,pgfmath}
\def\luafun#1#2{
    \directlua{
        x = #1;
        y = #2;
       r=-25500/(x/1000-255/52)-5200-3.0897/8*y
       tex.print(r)}
} 

\begin{document}
\def\UABmValues{{14.9, 15.8, 17.7, 18.3, 19, 20, 21.1, 22.2, 24.3, 26.9, 30.1}}

\foreach[count = \i from 0] \k in {30, 35, ..., 80}
{
\pgfmathsetmacro{\myval}{\UABmValues[\i]}%
\luafun{\myval}{\k}\par
 }

\end{document}

enter image description here

2) old version with fp

\documentclass{scrartcl}
\usepackage{tikz,fp}
\newcommand\pgfmathparseFP[1]{
   \begingroup
        \FPeval\pgfmathresult{(#1)}
     \pgfmathsmuggle
     \pgfmathresult
   \endgroup
    }

\begin{document}

  %data values:
\def\UABmValues{{14.9, 15.8, 17.7, 18.3, 19, 20, 21.1, 22.2, 24.3, 26.9, 30.1}}

%prints the result to the console:
\foreach[count = \i from 0] \k in {30, 35, ..., 80}
{
\pgfmathsetmacro{\myval}{\UABmValues[\i]}%
\pgfmathparseFP{-25500/(\myval/1000-255/52)-5200-3.0897/8*\k}\i, \pgfmathresult\par
 }

\end{document}

enter image description here

5
  • What is the drawback of doing so per default? I mean, pgfmath could be patched like this. Dec 26 '19 at 14:04
  • 3
    @OlegLobachev maintenance. The maintainers of TikZ don't want to use expl3 and have their reasons for doing so.
    – Skillmon
    Dec 26 '19 at 14:20
  • @OlegLobachev Balance between speed and precision. pgfmath is used usefully by some libraries and precision is not always as important Dec 26 '19 at 14:25
  • I don't know how to use more digits with lua Dec 26 '19 at 15:37
  • 4
    @OlegLobachev One of the reasons is performance. It would essentially double the load time. See here for a discussion.
    – user194703
    Dec 26 '19 at 15:50
6

An implementation with the CAS Sage(math) and SageTeX:

enter image description here

I use arara: sagetex for compiling.

% arara: pdflatex
% arara: sagetex
% arara: pdflatex

\documentclass{scrartcl}
\usepackage{sagetex, amsmath}
\usepackage{tikz}
\usetikzlibrary{fpu}
\newcommand\pgfmathparseFPU[1]{
\begingroup
\pgfkeys{
 /pgf/fpu,
/pgf/fpu/output format = fixed
}
\pgfmathparse{#1}
\pgfmathsmuggle
\pgfmathresult
\endgroup}

\begin{document}
%data values:
\def\UABmValues{{14.9, 15.8, 17.7, 18.3, 19, 20, 21.1, 22.2, 24.3, 26.9, 30.1}}

\section{pgfmath}
\foreach[count = \i from 0] \k in {30, 35, ..., 80}
{
\pgfmathsetmacro{\UABmValues}{\UABmValues[\i]}
\pgfmathparseFPU{-25500 / (\UABmValues / 1000 - 255 / 52) - 5200 - 3.0897 / 8 * \k}\noindent\i, \UABmValues, \pgfmathresult \\
}

\section{SageTeX}
\subsection{Sage-Output}
$\sagestr{MyOut}$

\subsection{From sageblock or sagesilent}
\begin{sageblock}
Val = ([14.9, 15.8, 17.7, 18.3, 19, 20, 21.1, 22.2, 24.3, 26.9, 30.1])
## Test:
#print Val[1]
#print len(Val)

# Function
f(x,y) = -25500/(x/1000 - 255/52) -5200 -3.0897/8 *(30+5*y)

# Short Output
#for i in range (len(Val)): print i,',',float(Val[i]),',', f(Val[i],i)

# Better Output    
data = [(i,  float(Val[i]), f(Val[i],i)) for i in range(len(Val))] 
data_str = [',   '.join(map(str, t)) for t in data] 
data_str = '\n'.join(data_str) 

MyOut = latex(data_str)
#print data_str
\end{sageblock}
\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.