2

I want to format a table with polynomials in each column. These polynomials do not necessarily have the same degree, and their coefficients can be any rational number. The terms of the polynomial should be displayed in a way such that terms on different rows cannot be confused (e.g. x3 being mistaken for x2).

At first I used tabular, but having to wrap every polynomial in $'s became inconvenient, so I used array + $ as recommended here.

\documentclass{standalone}
\begin{document}
  $\begin{array}{r|r|r|r}
     d & u & v & q \\
     x^5 + 3x^3 + x^2 + 2x + 1 & 1 &  0 & \\
     x^4 + 5x^3 -5x^2 - 5x - 6 & 0 &  1 & \\
    5x^4 + 8x^3 +6x^2 + 8x + 1 & 1 & -x & x \\
  \end{array}$
\end{document}

This gives the following result.

The left part of the first two polynomials are misaligned. How can I achieve the following effect (where the terms and operators are horizontally aligned)?

            d             |  u  |  v  | q
--------------------------+-----+-----+---
x5    + 3x3 +  x2 + 2x + 1 |   1 |   0 |
   x4 + 5x3 - 5x2 - 5x - 6 |   0 |   1 |
  5x4 + 8x3 + 6x2 + 8x + 1 |   1 |  -x | x

(the table shows the Extended Euclidean Algorithm for two polynomials in ℚ[x])

3

When the polynomials are aligned well, the only part with a varying width is the coefficient. So I used separate columns for the operator (+/-), coefficient and xn. And to avoid too much horizontal spacing, I added @{} between each right-aligning column specifier r (documented in the array package).

With that method, the polynomial f(x) can be written as x^5 & & & + & 3x^3 & + & x^2 & + & 2x & + & 1. This is quite difficult to read in the source (due to the repetitive &s and x^is), so I defined some (recursive) macros:

  1. \polyCols{N} to create N repetitions of r@{}r@{}... as array options.
  2. \poly[N]{..}{..}... to create a polynomial of degree N. E.g. \poly[2]{-}{5}{}{}{+}{1} expands to - & 5x^2 & & & + & 1 &.

The result looks like this:

preview

\documentclass{standalone}
% #1 = deg(f), #2 = ignored, #3 = operator, #4 = coefficient
\newcommand\polyRecursiveImplementation[4][0]{
  #3 &
  \ifx\\#4\\ % Do not print a term if the coefficient is missing
  \else
    \ifnum#1=0  % Just show the coefficient for x^0
      #4
    \else
      \ifnum#1=1 % Show "x" if the exponent is 1.
        \if1#4\else#4\fi x
      \else      % Show "x^e" otherwise.
        \if1#4\else#4\fi x^{#1}
      \fi % \if1#4\else#4\fi = Only show the coefficient if it's not 1.
    \fi
  \fi
  &
  \ifnum0<#1
    \polyRecursiveImplementation[\the\numexpr#1-1]
  \fi
}

% Usage: \poly[deg(f)]{sign}{term} (repeat {..}{..} deg(f) times)
\newcommand\poly[3][0]{\polyRecursiveImplementation[#1]{}{#2}{#3}}

% Create a specifier for #1 polynomial terms.
\newcommand\polyCols[1]{
  \ifnum0<#1
    r@{}r@{}
    \polyCols{\the\numexpr#1-1}
  \fi
}

\begin{document}
$\begin{array}{
  \polyCols{6}@{\hskip\tabcolsep}|
  \polyCols{6}@{\hskip\tabcolsep}|
  \polyCols{6}@{\hskip\tabcolsep}|
  \polyCols{6}r
}
\multicolumn{12}{c|}{d} &
\multicolumn{12}{c|}{u} &
\multicolumn{12}{c|}{v} &
\multicolumn{12}{c}{q} & \\
\hline

\poly[5]{}{1}{}{}{+}{3}{+}{1}{+}{2}{+}{1}
\poly[5]{}{}{}{}{}{}{}{}{}{}{}{1}
\poly[5]{}{}{}{}{}{}{}{}{}{}{}{0}
\poly[5]{}{}{}{}{}{}{}{}{}{}{}{} \\

\poly[5]{}{}{}{1}{-}{5}{-}{5}{-}{5}{-}{6}
\poly[5]{}{}{}{}{}{}{}{}{}{}{}{0}
\poly[5]{}{}{}{}{}{}{}{}{}{}{}{1}
\poly[5]{}{}{}{}{}{}{}{}{}{}{}{} \\

\poly[5]{}{}{}{5}{+}{8}{+}{6}{+}{8}{+}{1}
\poly[5]{}{}{}{}{}{}{}{}{}{}{}{0}
\poly[5]{}{}{}{}{}{}{}{}{-}{1}{}{}
\poly[5]{}{}{}{}{}{}{}{}{}{1}{}{} \\

\end{array}$
\end{document}

Elaboration of code

This was my first non-trivial macro, and while constructing it I encountered some problems. Here are some of the issues that I found, and how I resolved them:

  • Macros can take at most 9 parameters. This answer showed how to handle more arguments; by ending a macro with an incomplete invocation of another macro. This other macro will then process the remaining parameters, so that the total number of parameters can exceed 9.

  • My parametric macro is recursive, but it has to end at some point. So I started with a conditional macro.

    % Example: Wrap n elements in parentheses
    \newcommand\foo[2]{ (#2) \ifnum0<#1 \foo{\the\numexpr#1-1} \fi}
    \foo{10}{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}
    

    This failed to compile (! File ended while scanning use of \foo.). Apparently the presence of the \if...\if appends an extra variable. To solve this, I declared the first positional parameter as optional (\newcommand[N][...]{...}) and ignored the second parameter.
    Using this construction, I can pass a counter as a parameter to the macro, and process new elements.

    % #1 = count, #2 = ignored #3 = value to be wrapped in parentheses
    \newcommand\fooImpl[3][0]{ (#3) \ifnum0<#1 \fooImpl[\the\numexpr#1-1] \fi}
    \newcommand\foo[2]{\fooImpl[#1]{}{#2}}
    \foo{10}{0)(1}{2}{3}{4}{5}{6}{7}{8}{9}{10}
    % Output : (0)(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)
    

    The above minimal example consumes one parameter per iteration, whereas my actual macros (\poly and \polyRecursiveImplementation) takes two.
    And to enhance readability, I marked the first parameter of \poly as optional so that it's clear that the value between [ and ] is used to specify the number of polynomial terms, and the {...}{...} specifies the sign and coefficient of each term.

  • Initially, I wanted to omit the last & of the last term in the macro. This conditional logic is not possible due to "Incomplete \ifnum; all text was ignored after line"), so every row has one superfluous &.

Note that it is important that the number of parameters have to match. If you get an error after copying and changing my example, check whether the number of parameters matches (\foo[N]{1}{2}...{N+1}).

2
  • The spacing around +'s (and minuses) is awful. – Przemysław Scherwentke Sep 16 '15 at 19:26
  • @PrzemysławScherwentke If you dislike the spacing, then you could put some width in @{}, e.g. @{\hspace{3pt}}. Four polynomials next to each other takes lot of space, so I tried to be economic with horizontal spacing. – Rob W Sep 16 '15 at 19:28

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.