3

I was trying to draw a Pierson-Moskowitz wave spectrum in TikZ and had to load the PGF's fpu library to do some of the calculations.

Lots of errors!

What surprised me is that one of them doesn't have to do with my wave spectrum, but with the tape shape from the shapes.symbols library:

\documentclass[tikz]{standalone}

\usetikzlibrary{shapes.symbols}
\usetikzlibrary{fpu}

\begin{document}

\pgfkeys{/pgf/fpu=true,/pgf/fpu/output format=fixed}
\begin{tikzpicture}
  \node [tape] (model) {Do stuff};
\end{tikzpicture}

\end{document}

this raises the ill-formatted floating point number.

Why is the FPU incompatible with this (apparently simple) library?

  • My experience has been that if TikZ can use the FPU, it will, and not to mess around with the pgfkeys. – John Kormylo Aug 26 '18 at 14:47
  • @JohnKormylo First I tried without explicitly setting the FPU. The thing is that if I don't use the FPU then I can't draw the function I want because of "dimension too large". I already managed to work around the issue, but I asked because I don't think that the FPU should break one of TikZ's standard libraries. – Phelype Oleinik Aug 26 '18 at 14:58
  • Do you have to set the pgfkeys globally or is it sufficient to set it just locally where you need it? – user121799 Aug 26 '18 at 15:08
  • @JohnKormylo Indeed, it can, bot for my purposes it works. As I said my question is about the incompatibility of the FPU and a simple library. – Phelype Oleinik Aug 26 '18 at 15:09
  • @marmot That's what I did to have my picture working. I'm curious about the incompatibility :) – Phelype Oleinik Aug 26 '18 at 15:10
2

It is not possible to use fpu "just so" when you use some basic pgf routines such as the ones employed in the tape shape. However, it is possible to use it locally where it matters. That is, you can switch it on locally in a group and the use \pgfmathsmuggle, which was added to pgf long after this question was written (internal versions were available before), to smuggle the result of a computation out of the group. This allows you to define functions which yield reasonably small values but go over large values when parsing the expression. The function under your link is a good example since it involves high powers of the argument, omega, but the result is not too extreme because these large values cancel.

\documentclass[tikz]{standalone}
\usetikzlibrary{shapes.symbols}
\usetikzlibrary{fpu}
\newcommand{\pgfmathparseFPU}[1]{\begingroup%
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}%
\pgfmathparse{#1}%
\pgfmathsmuggle\pgfmathresult\endgroup}
\pgfmathdeclarefunction{SPM}{4}{\begingroup% #1=omega,#2=omega_p,#3=alpha,#4=beta
\pgfmathparseFPU{(#2/pow(#1,5))*exp(-#4*pow(#2/#1,4))}%
\pgfmathsmuggle\pgfmathresult\endgroup} 

\begin{document}
\pgfmathsetmacro{\xtest}{SPM(1,1,1,1)}
\begin{tikzpicture}
  \draw[stealth-stealth] (0,4) node[below left] {$S_\mathrm{PM}(\omega) $ }|- (5,0) node[below left] {$\omega$ };
  \draw[blue,thick] plot[variable=\x,domain=0.2:5,smooth,samples=71] (\x,{4*SPM(\x,1,1,1)});
  \node [tape,below right,draw] at (0.1,4){$\displaystyle S_\mathrm{PM}(\omega) 
  = \frac{\alpha g^2}{\omega^5} \exp \left [-\beta \left (\frac{\omega_p}{\omega} \right )^4 \right ]$};
\end{tikzpicture}
\end{document}

enter image description here

Needless to say that the canonical way to produce this plot is using pgfplots, which also switches on fpu only where it is needed.

\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{shapes.symbols}
\pgfplotsset{compat=1.16}
\begin{document}
\begin{tikzpicture}[declare function={SPM(\omega,\omegap,\alpha,\beta)=%
 (\omegap/pow(\omega,5))*exp(-\beta*pow(\omegap/\omega,4));}]
 \begin{axis}[xlabel=$\omega$,ylabel=$S_\mathrm{PM}(\omega)$,ymax=0.8]
  \addplot[domain=0.2:5,smooth,samples=71,blue,thick] {SPM(x,1,1,1)};
  \node[below right,draw,tape] at (0.2,0.75) {$\displaystyle S_\mathrm{PM}(\omega) 
  = \frac{\alpha g^2}{\omega^5} \exp \left [-\beta \left
  (\frac{\omega_p}{\omega} \right )^4 \right ]$};
 \end{axis}
\end{tikzpicture}
\end{document}

enter image description here

Yet there are definitely applications where locally switching on fpu makes sense, such as this one from the answer of which I copied (more or less) the code for this answer.

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.