6

I need a macro that behaves the following:

\mpoly{x}{1}{2} outputs (x+1)(x+2)

\mpoly{x}{1}{2}{3} outputs (x+1)(x+2)(x+3)

\mpoly{x}{1}{2}{3}{5} outputs (x+1)(x+2)(x+3)(x+5)

and so on. I am not at all confident with the variable length argument processing by tex. Could anyone help me with this?

  • 2
    Will the arguments of \mpoly always be either a single letter or a single number, or could they be more general inputs? And how is LaTeX supposed to "know" if some argument in curly braces is (a) still another argument of \mpoly or (b) some other document element? – Mico Apr 25 '18 at 10:59
9

I streamline the syntax by putting all the term data in a comma separated list in the 2nd argument. I use listofitems to parse the list (the default list separtor is a comma, but that could be changed). The package's \foreachitem macro allows easy regurgitation.

\documentclass{report}
\usepackage{listofitems}
\newcommand\mpoly[2]{%
  \readlist\myterms{#2}%
  \foreachitem\x\in\myterms{(#1+\x)}%
}
\begin{document}
$y_1 =\mpoly{x}{1,2}$

$y_2 =\mpoly{x}{1,2,3}$

$y_3 = \mpoly{x}{1,2,3,5}$
\end{document}

enter image description here

This can be generalized to a more inclusive format, with the use of nested parsing, to allow multiple variables as well as setting the +/- operation:

\documentclass{report}
\usepackage{listofitems}
\newcommand\mpoly[1]{%
  \setsepchar{*/+||-/,}
  \readlist\myterms{#1}%
  \foreachitem\x\in\myterms[]{
    \foreachitem\y\in\myterms[\xcnt,2]{(\myterms[\xcnt,1]\mytermssep[\xcnt,1]\y)}%
  }%
}
\begin{document}
$y_1 =\mpoly{x+1,2 * y-3,4}$

$y_2 =\mpoly{x+2,3 * x-4,5,6,7}$

$y_3 = \mpoly{x-1,2 * y+3,5 * z-6}$
\end{document}

enter image description here

  • +1. Very nice use of the listofitems package! – Mico Apr 25 '18 at 11:03
  • 1
    @mxant I have generalized the solution. – Steven B. Segletes Apr 25 '18 at 11:21
  • 1
    @Mico I made it even nicer. – Steven B. Segletes Apr 25 '18 at 11:32
2

Different syntax could be more flexible:

\usepackage{pgffor}
\newcommand*\mpoly[2]{\foreach\x in{#2}{(#1\x)}}

That would let you do \mpoly{x-}{1,2,3} or \mpoly{x+}{2,...,5}.

Another option could be

\newcommand*\mpolyn[3]{\foreach\x in{#3}{(#1#2\x)}}

That would let you do \mpolyn x-{1,2,3} or \mpolyn x+{2,...,5}. Or may be cleaner definition for this last synax

\newcommand\mpolyn{}
\protected\def\mpolyn#1#{\mpolynaux{#1}}
\protected\def\mpolynaux#1#2{\foreach\x in{#2}{(#1\x)}}

And that way you can \mpolyn xyz - {1,2,3} or \mpolyn \ln(x) + {2,...,5} for instance.

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.