The problem
The problem is actually not restricted to the bmatrix
environment, as can be seen from the following example:
\documentclass{beamer}
\usepackage{showframe} %% <- make the text area visible
\begin{document}
\begin{frame}
\begin{align}
\label{eq:1}
A %% <- This is fine
\end{align}
\begin{align}
\label{eq:2}
\left(A\right) %% <- Not fine
\end{align}
\begin{align}
\label{eq:3}
-A %% <- Not fine
\end{align}
\begin{align}
\label{eq:4}
\begin{bmatrix}A\end{bmatrix} %% <- Not fine
\end{align}
\begin{align}
\begin{bmatrix}A\end{bmatrix} %% <- This is fine
\end{align}
\end{frame}
\end{document}

This occurs due to the fact that beamer
modifies \label
and that the modified command creates an \hbox
.
This \hbox
itself takes up no space, but since it is part of the equation it can cause horizontal skips to be inserted when it is followed or preceded by particular types of objects.
This for instance happens if it is preceded/followed by a binary operator (like +
or -
), a binary relation (like =
or <
), an operator like (\sin
or \sum
) OR an "inner atom" like \left[
and \right]
.
(I'm not going to list all possibilities, but see the table in this answer.)
In your case, a \thinmuskip
(as produced by \,
) is inserted between this \hbox
and the \left[
at the start of a bmatrix
.
In the -A
example above, a \medmuskip
(as produced by \:
) is inserted before the -
and another \medmuskip
is inserted after it because this operator is now interpreted as a binary operator!
The reason why this messes up the placement of the equation label is that align
typesets its contents twice: once to measure its size and once for real.
During the "measuring phase", \label
is redefined to do nothing, which in particular means that it will not insert the aforementioned \hbox
when it is just being measured.
Consequently, amsmath
ends up measuring the width of the cell incorrectly and using this incorrect value to determine how much space should be inserted before/after/between columns.
Solutions
(1) Manual solution
Using {\label{<name>}}
(or e.g. \label{<name>}{}
or \label{<name>}\hbox{}
) only partially solves this problem.
If this is used, amsmath
will still see an empty group ({}
) during the measuring phase, which is the same as a \hbox{…}
and {\hbox{…}}
for spacing purposes.
It thus fixes the placement of the equation number by introducing the same unnecessary skip during the measuring phase.
(Also: the space between -
and A
in the third equation above will still be wrong!)
If you want to solve this without hacking beamer
's redefinition of \label
, you can replace \label{<name>}
by \mathopen{\label{<name>}}
if used at the start of a cell.
This works because no space is ever inserted after an Open atom.
\documentclass{beamer}
\usepackage{showframe} %% <- make the text area visible
\begin{document}
\begin{frame}
\begin{align}
\label{eq:1}
A %% <- Still fine
\end{align}
\begin{align}
\mathopen{\label{eq:2}}
\left(A\right) %% <- Now fine!
\end{align}
\begin{align}
\mathopen{\label{eq:3}}
-A %% <- Now fine!
\end{align}
\begin{align}
\mathopen{\label{eq:4}}
\begin{bmatrix}A\end{bmatrix} %% <- Now fine!
\end{align}
\begin{align}
\begin{bmatrix}A\end{bmatrix} %% <- Still fine
\end{align}
\end{frame}
\end{document}

(Note that also -A
is now also spaced correctly!)
(Replacing \label{<name>}
by \mathclose{\label{<name>}}
at the end of a cell usually works, but not quite always: a skip will still be inserted if the label is preceded by punctuation (like a ,
).)
(2) Patching beamer
You can also patch beamer
to make sure that no \hbox
is ever inserted in the first place.
The offending \hbox
can be found here (in beamerbasenavigation.sty
):
\def\beamer@inserttarget#1{%
\ifbeamer@inframe%
\ifvmode%
\nointerlineskip\vbox to0pt{#1}%
\else%
\hbox{#1}% %% <- This is the problem!
\fi%
\else% defer to next frame
\expandafter\gdef\expandafter\beamer@framehypertargets\expandafter{\beamer@framehypertargets#1}%
\fi%
}
(#1
is of the form \hypertarget{<label name>}{}
and it sets up the target for hyperlinks pointing to this equation.)
The problem is solved if this line is removed, but we don't want to do that since that'd destroy hyperlinks.
It would also be solved if \hbox{#1}
is replaced by #1
, but we don't want to do that either since that \hbox
is probably there for a reason (which probably does not apply in math mode).
So here is a proposal: if you add the following to your preamble, #1
will be inserted directly in math mode, and it will be \hbox
ed when used elsewhere.
\makeatletter %% <- make @ usable in command names
\patchcmd{\beamer@inserttarget}
{\hbox{#1}}{\ifmmode#1\else\hbox{#1}\fi}{}{}
\makeatother %% <- revert @
(\patchcmd
is part of the etoolbox
package, which is already loaded by beamer
.)
Here is the result:
\documentclass{beamer}
\usepackage{showframe} %% <- make the text area visible
\makeatletter %% <- make @ usable in command names
\patchcmd{\beamer@inserttarget}
{\hbox{#1}}{\ifmmode#1\else\hbox{#1}\fi}{}{}
\makeatother %% <- revert @
\begin{document}
\begin{frame}
\begin{align}
\label{eq:1}
A %% <- Still fine
\end{align}
\begin{align}
\label{eq:2}
\left(A\right) %% <- Also fine!
\end{align}
\begin{align}
\label{eq:3}
-A %% <- Also fine!
\end{align}
\begin{align}
\label{eq:4}
\begin{bmatrix}A\end{bmatrix} %% <- Also fine!
\end{align}
\begin{align}
\begin{bmatrix}A\end{bmatrix} %% <- Still fine
\end{align}
\end{frame}
\begin{frame}
The hyperlinks in the references \ref{eq:1} and \ref{eq:4} still work.
\end{frame}
\end{document}
