2

I want a way to set matrix entries aligned by their sign automatically. For example, output of

\begin{bmatrix}
    1&1&-1\\
    -1&1& 1\\
    1&-1& 1
\end{bmatrix}

be same as output of

\begin{bmatrix}
    \phantom{-}1&\phantom{-}1&-1\\
    -1&\phantom{-}1& \phantom{-}1\\
    \phantom{-}1&-1& \phantom{-}1
\end{bmatrix}

Is it possible at all?

  • 3
    Wouldn't it be simpler to use \begin{bmatrix*}[r] ... \end{bmatrix*}, defined by mathtools? – Bernard Jan 2 at 22:02
  • yes. that's it. Now is it possible to redefine \begin{bmatrix}... \end{bmatrix} as \begin{bmatrix*}[r] ... \end{bmatrix*}? – C.F.G Jan 2 at 22:27
  • I never tried it, but it might work. Other than that a ‘search and replace’ from within your editor would be fine too. – Bernard Jan 2 at 23:57
4

Here are two more proposals. The first one is conceptually very similar to Sebastiano's nice answer (and can be seen as an addendum to his). One can set the column type to r also with the mathtools package. The second proposal is based on this very nice answer, which solves a very related problem. It really does what you ask for, i.e. inserts a \phantom{-} if there is no minus, and comes in two variations, one with c and one with l columns (which I think makes more sense).

\documentclass{article}
\usepackage{mathtools}
\usepackage{array}% for second solution 
\makeatletter
\def\CheckMinus\ignorespaces{\@ifnextchar-{}{\phantom{-}}}
\makeatother
\newcolumntype{I}{>{\CheckMinus}c}
\newcolumntype{J}{>{\CheckMinus}l}

\begin{document}
\begin{enumerate}
 \item Just mathtools and change column type to \texttt{r}.
\[
\begin{bmatrix*}[r]
    1&1&-1\\
    -1&1& 1\\
    1&-1& 1
\end{bmatrix*}\quad\text{and}\quad\begin{bmatrix*}[r]
    12&1&-12\\
    -1&1& 12\\
    1&-12& 1
\end{bmatrix*}
\]
 \item Insert \verb|\phantom{-}| if there is no minus and use \texttt{c} column.
\[
\begin{bmatrix*}[I]
    1&1&-1\\
    -1&1& 1\\
    1&-1& 1
\end{bmatrix*}\quad\text{and}\quad\begin{bmatrix*}[I]
    12&1&-12\\
    -1&1& 12\\
    1&-12& 1
\end{bmatrix*}
\]
 \item Insert \verb|\phantom{-}| if there is no minus and use \texttt{l} column.
\[
\begin{bmatrix*}[J]
    1&1&-1\\
    -1&1& 1\\
    1&-1& 1
\end{bmatrix*}\quad\text{and}\quad\begin{bmatrix*}[J]
    12&1&-12\\
    -1&1& 12\\
    1&-12& 1
\end{bmatrix*}
\]
\end{enumerate}
\end{document}

enter image description here

| improve this answer | |
4

The amsmath environments [pbBvV]?matrix use a common \env@matrix macro to start the alignment. In this macro there is \array{*\c@MaxMatrixCols c}, which centers the contents of the cells by default. One quick way to change that default globally is to redefine that macro with r instead of c, or load etoolbox and do \patchcmd\env@matrix{c}{r}{}{}.

Alternatively, you can redefine \env@matrix to take an argument for the alignment, and patch the environments which use it to check for such optional argument. This is essentially what mathtools's starred environments do.

In the code below I used a loop to patch all the environments in one go (with a single default), but you can change them selectively if you want different behaviours.

Also, if you use a right aligned cell, then the numbers will be right aligned (thanks, Sherlock), and if two numbers have different widths (say, -1 and -12), then their rightmost end will be aligned, not the minus signs. To align the minus sign you can use the J column type defined (and not defined) in Schrödinger's cat's answer.

enter image description here

\documentclass{article}
\usepackage{amsmath}
\usepackage{array}
\usepackage{etoolbox}
\makeatletter
\def\env@matrix[#1]{\hskip -\arraycolsep
  \let\@ifnextchar\new@ifnextchar
  \array{*\c@MaxMatrixCols #1}}
\@tfor\@temp:=\matrix\pmatrix\bmatrix\Bmatrix\vmatrix\Vmatrix\do
  {\expandafter\patchcmd\@temp
     {\env@matrix}
     {\@ifnextchar[%]   default V
        \env@matrix{\env@matrix[J]}}
     {}{\FAILED}}
% From Mr. Cat's answer: https://tex.stackexchange.com/a/522747/134574
\newcolumntype{J}{>{\CheckSign}l}
\def\CheckSign\ignorespaces{%
  \@ifnextchar-{}{\@ifnextchar+{}{\phantom{-}}}}
\makeatother
\begin{document}
\[
\begin{bmatrix}
    1&1&-1\\
    -1&1& 1\\
    1&-1&-12\\
    1&-1&+12
\end{bmatrix}
\]
\end{document}
| improve this answer | |
  • Nice. But if I change $m_{33}$ to $-12$ same problem appear again. – C.F.G Jan 3 at 6:36
  • @C.F.G Initially I based my answer off of this comment of yours. I added the sign check in Schrödinger's cat's answer to use left aligned cells with a slot for unary signs. – Phelype Oleinik Jan 3 at 13:35
  • Sorry, I did not want to annoy you. ;-) I thought about the +, too, but then I thought that there could be \pm, a \mp, all of which would arguably make more sense than just a +, and I let it be in the end because it may easily become a never-ending story. That is, - signs are rather frequent, and for them it makes IMHO more sense to write an automatic solution than for all the other cases, which seem to be much rarer. – user194703 Jan 3 at 17:26
  • @Schrödinger'scat When did you annoy me? Indeed, a - is by far mode common than the other cases you mentioned (which I haven't thought about :-). I'll leave the code for + in case someone needs to extend the code for their needs. – Phelype Oleinik Jan 3 at 18:12
3

You can use the spalign package. Here there is an example for your request.

enter image description here

%% Compile and read me!
\documentclass[a4paper,12pt]{article}
\usepackage{spalign}
\begin{document}
\[ \spalignmat[r]{-1 1 -1; -1 1 1; 1 -1 1} \]
\end{document}
| improve this answer | |

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.