Using display style fraction in a matrix environment
This answer consists of three parts:
- a solution with manual adjustment of the vertical spacing,
- a solution with a modified
\arraystretch
that automatically centers the brackets around the matrix properly (unlike the original\arraystretch
!), - an explanation of the ugly default spacing.
The easy answer
You have two issues here:
The spacing is ugly – the matrix entries actually overlap slightly.
The matrix entries do not entirely fit between the brackets.
Issue #2 is in fact by design since you have a default \delimitershortfall
of 5pt
, which means that at most 5pt
of the entries are not "covered" by the brackets. Thus, an easy solution (with manually adjusted vertical space, as in the first part of Gonzalo's answer) would be
\documentclass{article}
\usepackage{amsmath}
\begin{document}
\[
\setlength{\delimitershortfall}{0pt}
\begin{bmatrix}
\dfrac{\partial f}{\partial x}
\\[2ex]
\dfrac{\partial f}{\partial y}
\end{bmatrix}
\]
\end{document}
(The redefinition of \delimitershortfall
is local to the displayed formula.) It is interesting to note that adding much less vertical space, say 0.5ex
, has no effect whatsoever; I will explain this near the bottom of the answer.
Using \arraystretch
If your matrix has a lot of rows, adding \\[2ex]
every time is annoying, and it becomes a nuisance when you want to adjust the spacing. In this case, percusse's idea to use \arraystretch
is great in principle. The problem is, as percusse discovered: \arraystretch
adds more space at the top of the matrix than at the bottom. This becomes very obvious if you take a large value, say \renewcommand{\arraystretch}{2.5}
:
Gonzalo offers a manual adjustment for this in the second part of his answer, but it would be nicer if it just worked out of the box! The cause for the peculiar behaviour of \arraystretch
lies in it's implementation, which is suitable for text arrays, but not for math arrays as I'll explain at the end of the answer.
In the code below I offer a \CenteredArraystretch
command that takes as mandatory argument the desired \arraystretch
. In the image I compare \renewcommand{\arraystretch}{2.5}
, \CenteredArraystretch{2.5}
and \CenteredArraystretch{2.1}
. The latter is quite agreeable in my opinion:
Note that with \arraystretch
you usually won't have to modify \delimitershortfall
any more! The code works by hacking into LaTeX's array
and needs etoolbox
for patching \@mkpream
.
\documentclass{article}
\usepackage{amsmath,etoolbox}
\makeatletter
\newif\ifcenter@asb@\center@asb@false
\def\center@arstrutbox{%
\setbox\@arstrutbox\hbox{$\vcenter{\box\@arstrutbox}$}%
}
\newcommand*{\CenteredArraystretch}[1]{%
\ifcenter@asb@\else
\pretocmd{\@mkpream}{\center@arstrutbox}{}{}%
\center@asb@true
\fi
\renewcommand{\arraystretch}{#1}%
}
\makeatother
\newcommand*\testvector{
\begin{bmatrix}
\dfrac{\partial f}{\partial x}
\\
\dfrac{\partial f}{\partial y}
\end{bmatrix}
}
\begin{document}
\[
\renewcommand{\arraystretch}{2.5}
\testvector
\CenteredArraystretch{2.5}
\testvector
\CenteredArraystretch{2.1}
\testvector
\]
\end{document}
Why is the default spacing so ugly?
The reason for the slight overlap is that \partial
sticks out of its bounding box a little; in the image I show only the top and the bottom:
But why are the two fractions just put on top of each other by default? The reason lies in the implementation of bmatrix
, which is based on the LaTeX array
. (The plain TeX \matrix
would put a vertical space of 1pt
between the fractions!)
Here's how array
works: Each row gets a minimum height and a minimum depth, defined by the height and depth of \strutbox
. If the actual height and depth of your entries are larger, then the \strutbox
has no effect. (This is the case for the displaystyle fractions.) Then the rows are just put on top of each other, without additional vertical space. This implementation results in good spacing only if the actual material in the rows has "usual" small height and depth.
Now I can explain why \\[0.5ex]
has no effect in the first part of my answer: simply put, the 0.5ex
are just added to the depth of the \strutbox
(3.6pt
), and together this is still less than the depth of \dfrac{\partial f}{\partial x}
(6.86pt
). Thus, you'll only get an effect if you add more that 3.26pt
vertical space!
Moreover, I can explain why \arraystretch
adds too much space at the top of the matrix: LaTeX increases both the height and the depth of the \strutbox
by the factor \arraystretch
. Now the point is that the height (8.4pt
) is much larger than the depth (3.6pt
), so with an \arraystretch
of 2
, 8.4pt
are added at the top of the matrix, and only 3.6pt
at the bottom. For a text array this should be OK, but in a matrix things tend to be centered vertically with respect to the mathematical axis (like fractions and integrals), so when they get large, they have equal increase in height and depth.
What I don't know is why the above implementation of array
was chosen in LaTeX. I guess that for text arrays it makes a lot of sense, but it appears that it's not optimal for matrices.
You can stick some \strut
s in there (the height+depth of a paren):
\documentclass{article}
\usepackage{mathtools}
\begin{document}
\[
\begin{bmatrix}
\dfrac{\strut\partial f}{\strut\partial x}
\\
\dfrac{\strut\partial f}{\strut\partial y}
\end{bmatrix}
\]
\end{document}
You can use the optional argument of \\
to add vertical space and some zero-width rules to increase the length of the delimiters:
\documentclass{article}
\usepackage{mathtools}
\begin{document}
\[
\begin{bmatrix}
\dfrac{\partial f}{\partial x}\rule{0pt}{1.7em}
\\[1em]
\dfrac{\partial f}{\partial y}\rule[-1.2em]{0pt}{0em}
\end{bmatrix}
\]
\end{document}
Building on percusses's idea, you could define a new environment increasing \arraystretch
and adding some extra space for the last row. The first (optional) argument in my example controls the redefinition of \arraystretch
; the second (mandatory) argument controls the spacing after the last row:
\documentclass[12pt]{article}
\usepackage{mathtools}
\newcommand\myfact{}
\newenvironment{Mybmatrix}[2][1.8]
{\renewcommand\myfact{#2}\renewcommand{\arraystretch}{#1}\begin{bmatrix}}
{\\[-\myfact em]\mbox{}\end{bmatrix}}
\begin{document}
\[
\begin{Mybmatrix}{2}
\dfrac{\partial f}{\partial x}
\\
\dfrac{\partial f}{\partial y}
\end{Mybmatrix}
\]
\end{document}
I don't know, however, how "robust" this definition will be.