Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I need a nested loop to animate PSTricks diagrams. In C# or C or C++, I usually write as follows.

int N=6;
for(int x=0; x<N; x++)
    for(int y=x+1; y<N; y++)
        Console.WriteLine("({0}, {1})",x,y);

I have attempted to do it in TeX as follows, but it does not work. :-)

\documentclass{minimal}
\usepackage{multido}

\newcommand\N{6}
\newcommand\Init{}
\newcommand\Freq{}
\begin{document}
\multido{\ix=0+1}{\N}
{
        \makeatletter
            \renewcommand\Init{\strip@pt\dimexpr\ix pt + 1pt\relax}         
            \renewcommand\Freq{\strip@pt\dimexpr\N pt - \Init pt\relax}
        \makeatother
        \multido{\iy=\Init+1}{\Freq}
        {
                (\ix, \iy)\par
        }
}
\end{document}

How to fix it?

share|improve this question

4 Answers 4

up vote 6 down vote accepted
\documentclass{minimal}
\usepackage{multido}

\newcommand\N{6}
\begin{document}
\multido{\ix=0+1,\ixB=1+1,\iN=5+-1}{\N}{%
  \multido{\iy=\ixB+1}{\iN}{(\ix, \iy)\endgraf}}
\end{document}

and with a counter:

\documentclass{minimal}
\usepackage{multido}
\newcommand\N{6}
\newcounter{NminusOne}
\setcounter{NminusOne}{\N}\addtocounter{NminusOne}{-1}

\begin{document}
\multido{\ix=0+1,\ixB=1+1,\iN=\theNminusOne+-1}{\N}{%
  \multido{\iy=\ixB+1}{\iN}{(\ix, \iy)\endgraf}}
\end{document}
share|improve this answer
    
Is there a trick to avoid hard-coding the value 5? –  xport Jul 23 '11 at 21:13
    
define two counters for N and NminusOne, then you can use these instead of \N and 5 –  Herbert Jul 23 '11 at 21:22
    
@Herbert: It seems useful to define \multido as a long macro. Is there any special reason that \multido isn't a long macro? If not, could you revise it to support \par? –  Leo Liu Jul 23 '11 at 21:36
    
@Leo: it is a really old package and only bug fixes will be done. Too many people use it in the meantime, modifications to the code may be dangerous. You can use \endgraf instead and all is fine. –  Herbert Jul 23 '11 at 21:48

You need to use \edef to expand the macro content. Using \renewcommand simply redefines the macro to the exact same content over and over again. That the \ix and \Init macros have a changing value doesn't matter here. You can't have a paragraph in \multido because it isn't defined \long. So use either \\ or hide the \par in a macro. You need also take care of spaces introduced by line breaks, e.g. after } and {. The \makeatletter and \makeatother macros must be places outside the \multido macro, otherwise it's already to late to change catcodes.

\documentclass{minimal}
\usepackage{multido}

\newcommand\N{6}
\newcommand\Init{}
\newcommand\Freq{}
\newcommand\mypar{\par}
\begin{document}
\makeatletter
\multido{\ix=0+1}{\N}{%
    \edef\Init{\strip@pt\dimexpr\ix pt + 1pt\relax}%
    \edef\Freq{\strip@pt\dimexpr\N pt - \Init pt\relax}%
    \multido{\iy=\Init+1}{\Freq}{%
        (\ix, \iy)\mypar
    }%
}
\makeatother
\end{document}
share|improve this answer
    
where is the sense to use \dimexpr when the unit is not needed? –  Herbert Jul 23 '11 at 20:58
    
Thank you for your answer. Especially introducing me to \edef. It might be used in another scenario in my life. :-) Since Herbert's solution is simpler than yours so I switched the green mark to Herbert's. –  xport Jul 23 '11 at 21:01
    
@Herbert: I didn't changed that part of xport's original code, simply fixed the other issues. The code works beside that. –  Martin Scharrer Jul 23 '11 at 21:02
    
@xport: That's fine. You shouldn't accept answers right away anyway. –  Martin Scharrer Jul 23 '11 at 21:02

The following is the simplified version of Herbert's answer.

\documentclass{minimal}
\usepackage{multido}
\newcommand\N{6}


\newcounter{NTemp}
\setcounter{NTemp}{\N}

\begin{document}
\multido{\ix=0+1,\iTemp=1+1}{\N}
{
  \addtocounter{NTemp}{-1}
  \multido{\iy=\iTemp+1}{\theNTemp}
  {
    (\ix, \iy)\endgraf
  }
}
\end{document}
share|improve this answer
\documentclass{minimal}
\usepackage{multido}


\newcommand{\N}{6}
\newcounter{Init}
\newcounter{Freq}
\setcounter{Freq}{\N}
\newcommand\mypar{\par}

\begin{document}
\multido{\ix=0+1}{\N}
{
    \setcounter{Init}{\ix}
    \addtocounter{Init}{1}
    \addtocounter{Freq}{-1}
    \multido{\iy=\value{Init}+1}{\value{Freq}}
    {
        (\ix, \iy)\endgraf
    }
}
\end{document}
share|improve this answer
    
see edited answer –  Herbert Jul 23 '11 at 21:41

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.