3

I'm trying to plot a normalized sinc function with PGFPlots/TikZ. As this is somewhat tricky because of the limiting value at 0, I used a suggestion provided by percusse.

Here's a minimal example (note that I've renamed the function to sincf due to conflicts with the rest of the document and inserted an approximation of Pi to normalize):

\documentclass{scrreprt}

\usepackage{pgfplots}
\pgfplotsset{compat=1.12}


\begin{document}
\begin{tikzpicture}

% https://tex.stackexchange.com/a/235009
\pgfmathdeclarefunction{sincf}{1}{%
        \pgfmathparse{abs(#1)<0.01 ? int(1) : int(0)}%
        \ifnum\pgfmathresult>0 %
            \pgfmathparse{1}%
        \else%
            \pgfmathparse{sin(3.14159*#1 r)/(3.14159*#1)}%
        \fi%
}

    \begin{axis}
        \addplot {sincf(\x)};
    \end{axis}

\end{tikzpicture}
\end{document}

However, I'm getting two errors which I can't figure out:

! Missing = inserted for \ifnum.
<to be read again>
Y
l.23 \addplot plot (\x,{sincf(\x)});
I was expecting to see `<', `=', or `>'. Didn't.

! Missing number, treated as zero.
<to be read again>
Y
l.23 \addplot plot (\x,{sincf(\x)});
A number should have been here; I inserted `0'.
(If you can't figure out why I needed to see a number,
look up `weird error' in the index to The TeXbook.)

Using MikTeX 2.9

  • The first cycle has \pgfmathresult=0Y0.0e0], so not a good value for \ifnum. – egreg Aug 21 '15 at 17:15
3

pgfplots uses library fpu for better precision by default, which has a different internal number format. Therefore \pgfresult is not 1 or 0 anymore and \ifnum cannot be used.

\tikzset{fpu}
\pgfmathparse{int(0)}\show\pgfmathresult
\pgfmathparse{int(1)}\show\pgfmathresult

The lines show 0Y0 for zero and 1Y1 for one.

In this case, the whole math can be put in one \pgfmathparse expression:

\documentclass{scrreprt}

\usepackage{pgfplots}
\pgfplotsset{compat=1.12}

\begin{document}
\begin{tikzpicture}

    % http://tex.stackexchange.com/a/235009
    \pgfmathdeclarefunction{sincf}{1}{%
        \pgfmathparse{(abs(#1)<0.01) ? 1 : sin(pi*#1 r)/(pi*#1)}%
    }

    \begin{axis}
        \addplot {sincf(\x)};
    \end{axis}

\end{tikzpicture}
\end{document}

Result

  • Short, but very detailed, precise and quick answer. Thanks a lot! So if I get it right, 0Y0 is an internal representation of fpu which can't be used with \ifnum. But then why did the code by percusse work? Is it because \draw plot doesn't use fpu in contrast to \addplot? – user2009388 Aug 21 '15 at 18:23
  • @user2009388 Exactly. – Heiko Oberdiek Aug 21 '15 at 18:35
  • Interesting. But then what does it use? – user2009388 Aug 21 '15 at 19:23
  • @user2009388 The default mathematical engine, unless a different is set explicitly, examples: library fpu with changed internal format, library fixedpointarithmetic, based on package fp, ... – Heiko Oberdiek Aug 21 '15 at 19:24
0

Using a related answer about fpu formatting, I was able to use \ifnum in the case that my result was within the range of an int() [−16383.9998, +16383.9998]. The trick is to use \pgfmathfloattofixed on the \pgfmathresult.

\pgfkeys{/pgf/fpu=true}
\pgfmathparse{...do floating point math here (with an int() result)...}
\pgfmathfloattofixed{\pgfmathresult} % this allows the conversion with int()
\edef\tmp{\pgfmathresult}
\pgfkeys{/pgf/fpu=false}
\pgfmathsetmacro\iTmp{int(\tmp)} % convert with int()

\ifnum \iTmp>0
  ... do stuff ...
\fi

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.