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 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}
share|improve this question
add comment

3 Answers

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}
share|improve this answer
    
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.) –  Jim Hefferon Dec 30 '11 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 '11 at 17:28
    
@JimHefferon A (not so nice) solution is on line –  egreg Dec 30 '11 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. –  Bruno Le Floch Dec 31 '11 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.) –  Jim Hefferon Dec 31 '11 at 11:33
add comment

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

share|improve this answer
add comment

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*}
share|improve this answer
    
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. –  Jim Hefferon Dec 30 '11 at 17:29
add comment

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.