6

I have lots of matrices so I want to define a mat environment. I sometimes need the matrix to have right-aligned columns so I am using mathtools and I want to have an optional argument that is usually c but that I can make r when I want.

A small working example is below. The definition works great in lots of cases, including inside the equation* but inside of align* it fails. Specifically, I get ! Extra }, or forgotten $. <recently read> } l.22 \end{align*}.

If I add [c] or [r] as optional arguments to the mat inside the align* then compilation will succeed. Adding a \ (slash, space) to the first line of the mat, before the &\vdots, also works.

To me this looks like a problem with LaTeX trying to read the optional argument when I don't want it to. I've tried putting %'s in various places in the \begin{pmatrix*}[#1] line but to no avail. Any suggestions?

\documentclass{article}
\RequirePackage{mathtools}
\newenvironment{mat}[1][c]{\begin{pmatrix*}[#1]
      }{\end{pmatrix*}}

\begin{document}
\begin{equation*}
  \begin{mat}
           &\vdots                    \\
    \cdots &ra_{j,i}+sb_{j,i} &\cdots \\
           &\vdots
  \end{mat}
\end{equation*}

\begin{align*}
  \begin{mat}
           &\vdots                    \\
    \cdots &ra_{j,i}+sb_{j,i} &\cdots \\
           &\vdots
  \end{mat}
  &= 0
\end{align*}
\end{document}

3 Answers 3

4

It's an expansion time problem. A way out comes from xparse:

\usepackage{mathtools,xparse}
\NewDocumentEnvironment{mat}{O{c}}
  {\begin{pmatrix*}[#1]}
  {\end{pmatrix*}}

Solution without xparse

Redefine \env@matrix, but not with \renewcommand:

\makeatletter
\def\env@matrix{\new@ifnextchar[\env@m@trix{\env@m@trix[c]}}
\def\env@m@trix[#1]{%
 \hskip-\arraycolsep\let\@ifnextchar\new@ifnextchar\array{*\c@MaxMatrixCols#1}}
\makeatother

This will allow you to use an optional argument to the Xmatrix environments; however you can't define an abbreviation with \newenvironment. This will work (with or without the optional argument)

\begin{align*}
  \begin{pmatrix}[r]
           &\vdots                    \\
    \cdots &ra_{j,i}+sb_{j,i} &\cdots \\
           &\vdots
  \end{pmatrix}
  &= 0
\end{align*}

If you want an abbreviation, then the magic formula

\expandafter\let\expandafter\mat\csname pmatrix*\endcsname
\expandafter\let\expandafter\endmat\csname endpmatrix*\endcsname

will allow you to write

\begin{align*}
  \begin{mat}
           &\vdots                    \\
    \cdots &ra_{j,i}+sb_{j,i} &\cdots \\
           &\vdots
  \end{mat}
\end{align}

with or without the optional argument.

Solution with minimal impact

(Thanks to Bruno Le Floch)

Write

\begin{mat}
\relax & \vdots                    \\
\cdots & ra_{j,i}+sb_{j,i} &\cdots \\
       & \vdots
\end{mat}
5
  • Thank you but that gives me an internal LaTeX3 error: Module kernel, message name "command-already-defined": Arguments '\if_num:w' and '\ifnum'. (However, my LaTeX3 is old since I use what comes stock with Ubuntu, so I think it is TeXLive 2009.) Dec 30, 2011 at 17:25
  • @JimHefferon I'll try and investigate more on a "pure LaTeX" solution that avoids braces around the environment. Upgrading to TeX Live 2011 is not so difficult.
    – egreg
    Dec 30, 2011 at 17:28
  • @JimHefferon A (not so nice) solution is on line
    – egreg
    Dec 30, 2011 at 18:14
  • 1
    @egreg The reason Jim's code fails is that LaTeX skips spaces when looking for the optional argument: then TeX sees & when looking for the optional arg, and the dreaded \halign cell-building mechanism is triggered. Three solutions: not skip spaces, as when you use xparse; surround the environment with braces, as in Herbert's answer (this effectively hides & from TeX); or do some hack similar to what AMSmath's own environment do with <code>\ifnum`{=0\fi\iffalse}\fi</code>. Also, your last mat* should be mat. Dec 31, 2011 at 6:39
  • Thank you to Bruno and egreg. (As I mentioned to Herbert, I have hundreds of instances of mat and I was hoping to avoid special-casing those that appear inside an align, or similar bad spot. But perhaps I cannot.) Dec 31, 2011 at 11:33
5

put the mat environment into braces:

\begin{align*}
 { \begin{mat}
           &\vdots                    \\
    \cdots &ra_{j,i}+sb_{j,i} &\cdots \\
           &\vdots
  \end{mat} }
  &= 0
\end{align*}
1
  • Thank you, Herbert. I have hundreds of instances of mat (it is a book) and I was hoping to avoid special-casing such as putting in the slash-space, or your solution. But perhaps I need to do that. Dec 30, 2011 at 17:29
0

I defined a new command for easy matrix typing:

\documentclass{article}
\RequirePackage{mathtools}

\newcommand{\pma}[2][r]{\begin{pmatrix*}[#1] #2 \end{pmatrix*} } %pmatrix shortcut

\begin{document}
    \begin{align*}
    \pma{
    &\vdots                    \\
    \cdots &ra_{j,i}+sb_{j,i} &\cdots \\
    &\vdots
    }
    &= 0
    \end{align*}
\end{document}

And I have no problems with align

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .