2

I want to represent a graph where the labels for each node are obtained computing a modulo computation. The first and easy way to do it is as follow :

\documentclass[tikz]{standalone}
\usetikzlibrary{graphs,graphs.standard}

\begin{document}
\begin{tikzpicture}
    \def \n {3}
    \graph[clockwise=\n,radius=3cm] {
        \foreach \x [evaluate=\x as \xn using {int(mod(\x+1,\n))}] in {0,...,\the\numexpr\n-1} {
            \foreach \y [evaluate=\y as \yn using {int(mod(\y+1,\n))}] in {\x,...,\the\numexpr\n-1} {
                \x / {$a_\x, a_\xn$} --
                \y / {$a_\y, a_\yn$};
            };
        };
    };
\end{tikzpicture}

\end{document}

enter image description here

Then I found out about pgfmathtruncatemacro and wrote

\documentclass[tikz]{standalone}
\usetikzlibrary{graphs,graphs.standard}

\begin{document}
\begin{tikzpicture}
    \def \n {3}
    \graph[clockwise=\n,radius=3cm] {
        \foreach \x in {0,...,\the\numexpr\n-1} {
            \pgfmathtruncatemacro{\xn}{mod(\x+1,\n)}%
            \foreach \y in {\x,...,\the\numexpr\n-1} {
                \pgfmathtruncatemacro{\yn}{mod(\y+1,\n)}%
                \x / {$a_\x, a_\xn$} --
                \y / {$a_\y, a_\yn$};
            };
        };
    };
\end{tikzpicture}

\end{document}

And strangely it gives me these errors :

! Undefined control sequence. \pgfmathsetcount ... \pgfmath@onquick #2\pgfmath@ {\afterassignment \pgfmath... l.16 } ; The control sequence at the end of the top line of your error message was never \def'ed. If you have misspelled it (e.g., \hobx'), typeI' and the correct spelling (e.g., `I\hbox'). Otherwise just continue, and I'll forget about whatever was undefined.

! Undefined control sequence. \tikz@lib@graph@handle@node@cont ...kzgraphnodeas \tikzgraphnodeas@default ... l.16 } ; The control sequence at the end of the top line of your error message was never \def'ed. If you have misspelled it (e.g., \hobx'), typeI' and the correct spelling (e.g., `I\hbox'). Otherwise just continue, and I'll forget about whatever was undefined.

! Undefined control sequence. \tikz@lib@graph@typesetter ->\tikzgraphnodetext l.16 } ; The control sequence at the end of the top line of your error message was never \def'ed. If you have misspelled it (e.g., \hobx'), typeI' and the correct spelling (e.g., `I\hbox'). Otherwise just continue, and I'll forget about whatever was undefined.

) ! Incomplete \iffalse; all text was ignored after line 16. \fi

And I really can't understand why it wouldn't work.

[EDIT] I wrote my second code based on this answer. The part where I write \n - 1 without \the\numexpr is not needed when working in Overleaf so it's NOT the problem here. And I don't want to have \pgfmathtruncatemacro in the labelling of the node since the answer I linked works perfectly for me too without needing it. My problem is that it looks buggy when using it in the \graph environment.

[EDIT 2] Added \the\numexpr since it would not compile on every installation of TL and since it was not this that made the program not work.

8
  • The issue is not the \pgfmathtruncatemacro but the \n-1 in the \foreach loop, and can be solved e.g. with \the\numexpr\n-1. However, even your first example does not compile.
    – user194703
    Oct 14 '19 at 13:52
  • @Schrödinger'scat Good point ! Another solution: add the new (?) parse=true option to the \foreach... Oct 14 '19 at 13:59
  • @PaulGaborit This is a nice option but I did experience issues, in particular with integers when trying to use it so I do not use it myself.
    – user194703
    Oct 14 '19 at 14:01
  • The \graph macro changes the syntax : you can't use TeX code directly. Here, you must use [/utils/exec={\pgfmathtruncatemacro{\xn}{mod(\x+1,\n)}}] instead of \pgfmathtruncatemacro{\xn}{mod(\x+1,\n)}... Oct 15 '19 at 6:07
  • 1
    @JosephWright Here, with the latest TL2018 (updated in april 2019), the first code compiles... And the same code with Overleaf distribution (TL 2018 by default) compiles also. Oct 15 '19 at 9:32
4

The \graph macro changes the syntax: you can't use TeX code directly. You can use the /utils/exec key to execute some arbitrary TeX code.

Here is a solution with the final version of TeXLive 2018 (used by Overleaf, cf. TeX Live upgrade Sep.2019):

\documentclass[tikz]{standalone}
\usetikzlibrary{graphs,graphs.standard}
\begin{document}
\begin{tikzpicture}
    \def \n {3}
    \graph[clockwise=\n,radius=3cm] {
        \foreach \x in {0,...,\n-1} {
            [/utils/exec={\pgfmathtruncatemacro{\xn}{mod(\x+1,\n)}}]%
            \foreach \y in {\x,...,\n-1} {
                [/utils/exec={\pgfmathtruncatemacro{\yn}{mod(\y+1,\n)}}]%
                \x / {$a_\x, a_\xn$} --
                \y / {$a_\y, a_\yn$};
            };
        };
    };
\end{tikzpicture}
\end{document}

And, here is a solution with TeXLive 2019:

\documentclass[tikz]{standalone}
\usetikzlibrary{graphs,graphs.standard}
\begin{document}
\begin{tikzpicture}
  \def\n{3}
  \graph[clockwise=\n,radius=3cm] {
    \foreach[parse=true] \x in {0,...,\n-1} {
      [/utils/exec={\pgfmathtruncatemacro{\xn}{mod(\x+1,\n)}}]
      \foreach[parse=true] \y in {\x,...,\n-1} {
        [/utils/exec={\pgfmathtruncatemacro{\yn}{mod(\y+1,\n)}}]
        \x / {$a_\x, a_\xn$} --
        \y / {$a_\y, a_\yn$};
      }
    }
  };
\end{tikzpicture}
\end{document}

Here is a solution with TeXLive 2019 using \pgfmathsetmacro to compute \xmax (without the parse option that still does not work very well):

\documentclass[tikz]{standalone}
\usetikzlibrary{graphs,graphs.standard}
\begin{document}
\begin{tikzpicture}
  \def\n{3}
  \graph[clockwise=\n,radius=3cm] {
    [/utils/exec={\pgfmathsetmacro\xmax{int(\n-1)}}]
    \foreach \x in {0,...,\xmax} {
      [/utils/exec={\pgfmathtruncatemacro{\xn}{mod(\x+1,\n)}}]
      \foreach \y in {\x,...,\xmax} {
        [/utils/exec={\pgfmathtruncatemacro{\yn}{mod(\y+1,\n)}}]
        \x / {$a_\x, a_\xn$} --
        \y / {$a_\y, a_\yn$};
      }
    }
  };
\end{tikzpicture}
\end{document}
5
  • I see. Overleaf does compile this. +1. (My problem with parse is that some things do not work, e.g. ` \foreach[parse=true] \x in {0,...,{int(\n-1)}}` gives an error.
    – user194703
    Oct 15 '19 at 6:38
  • @Schrödinger'scat I see the same problem. The parse option is probably not fully developed. Oct 15 '19 at 7:36
  • Yes. There are also some hidden gems like a function dim that returns the length of an array but does not always work. There are problems when the last item of the list is "non-atomic". (I do not know whether parse has been a hidden gem for a while, but I am pretty positive that it only made it to the manual very recently.)
    – user194703
    Oct 15 '19 at 7:40
  • Funny how the tone changes when talking to someone with a big score and a simple user asking a question. Thanks for your answer, I didn't know Overleaf was hiding error messages and I tried it on my distro this morning noticing the error messages. @Schrödinger'scat That's how you answer to someone. You may tell them they have some errors in their code asserting the fact that on their side the code may have compiled and thus answering their question. Or at least don't post a comment as an answer when it doesn't answer the question asked. Thanks for the remark about \n - 1 though.
    – Lhooq
    Oct 15 '19 at 8:50
  • @Lhooq Well, your code did and does not compile, and I pointed that out and fixed it. All you did was to charge into me and to downvote me. And now this remark. Well, you have presumably a way of interpreting this in your own way, and I have my way of rating this behavior. My tone did not change, I am just allergic to wrong statements and undeserved downvotes.
    – user194703
    Oct 15 '19 at 9:05
2

This is a compilable version of your first example. I do not see any benefit in using \pgfmathtruncatemacro since you'd also have to wrap it into \pgfextra and so on if you want to use it in a path.

\documentclass[tikz]{standalone}
\usetikzlibrary{graphs,graphs.standard}

\begin{document}
\begin{tikzpicture}
    \def \n {3}
    \graph[clockwise=\n,radius=3cm] {
        \foreach \x [evaluate=\x as \xn using {int(mod(\x+1,\n))}] in
        {0,...,\the\numexpr\n-1} {
            \foreach \y [evaluate=\y as \yn using {int(mod(\y+1,\n))}] in
            {\x,...,\the\numexpr\n-1} {
                \x / {$a_\x, a_\xn$} --
                \y / {$a_\y, a_\yn$}
            }
        }
    };
\end{tikzpicture}

\end{document}

And here is a version where \pgfmathtruncatemacro gets used. Luckily in this application the result is not needed for the path but only for typesetting. So you can add \pgfmathtruncatemacro just to the stuff you want to typeset.

\documentclass[tikz]{standalone}
\usetikzlibrary{graphs,graphs.standard}

\begin{document}
\begin{tikzpicture}
    \def \n {3}
    \graph[clockwise=\n,radius=3cm] {
        \foreach \x  in {0,...,\the\numexpr\n-1} {
            \foreach \y in {\x,...,\the\numexpr\n-1} {               
                \x / {$\pgfmathtruncatemacro{\xn}{int(mod(\x+1,\n))}a_\x, a_\xn$} --
                \y / {$\pgfmathtruncatemacro{\yn}{int(mod(\y+1,\n))}a_\y, a_\yn$}
            }
        }
    };
\end{tikzpicture}

\end{document}

enter image description here

0

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.