42

I'd like use the \dfrac command in a bmatrix environment as follows:

\documentclass{article}
\usepackage{amsmath}

\begin{document}

\[
\begin{bmatrix}
  \dfrac{\partial f}{\partial x}
  \\
  \dfrac{\partial f}{\partial y}
\end{bmatrix}
\]

\end{document}

Unfortunately, one gets pretty ugly spaced elements that do not entirely fit between matrix brackets

Without specifying magic line skip values, what is the proper way to fix this problem?

2
  • Why not using \cfrac{}{} instead of \dfrac{}{}? Commented Dec 11, 2021 at 19:52
  • Are you suggesting the (mis)use of a command intended for continuous fractions? Why would that be a good choice? Please explain in an answer.
    – caustic
    Commented Dec 12, 2021 at 1:08

8 Answers 8

34

You can stick some \struts 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}

enter image description here

2
  • 1
    Definitely most easy, without manual adjustment of spacing parameters - nice! Note that this solution also adds a bit vertical space around the fraction lines. (with f this is OK, but maybe not with h instead.) Commented Jun 26, 2012 at 18:30
  • @HendrikVogt: Yes, I tried with \mathstrut for h, but it looks wrong. Also, for the reader, I think my claim of a \strut being the height and depth of a paren is wrong (I think in LaTeX it is .7\baselineskip for height and .3\baselineskip for depth, and in plain they're fixed). IIRC, for the \mathstrut the claim would be correct.
    – morbusg
    Commented Jun 28, 2012 at 18:00
49

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:

  1. The spacing is ugly – the matrix entries actually overlap slightly.

  2. 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}

nicer matrix

(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}:
\arraystretch example

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:

comparison of 3 versions

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:
bounding box of \partial

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.

2
  • I like the second answer, but when I use \usepackage{siunitx}, the spacing is messed up (much too close) with Tex Live 2018 and LuaLaTex. Does anybody else have this problem?
    – Konne
    Commented Jun 13, 2018 at 13:07
  • Where goes the argument that the advantage of using LaTeX is that it lets you to concentrate on writing, and spend less time on presentation? Sorry for sarcasm. :)
    – facetus
    Commented Jun 23, 2020 at 9:22
8

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.

5
  • As already mentioned, I'd like to avoid this. Also, the problem with elements not fitting entirely into the matrix which can be seen in the question persists.
    – caustic
    Commented May 30, 2011 at 16:55
  • @caustic: I've updated my answer with a possible solution for the elements not fitting. I don't know if there is a more automated solution. Commented May 30, 2011 at 17:07
  • 2
    btw: this has nothing to do with mathtools, \dfrac stem from amsmath (if it isn't in the LaTeX core). mathtools automatically load amsmath
    – daleif
    Commented May 30, 2011 at 17:15
  • @daleif: I've updated the question.
    – caustic
    Commented May 30, 2011 at 17:26
  • @caustic: I've updated my answer with a new approach, using @percusses's idea. Commented May 30, 2011 at 17:30
5

I use the following frequently which might be what you wish. But it still lacks the extra space at the bottom.

\documentclass{article}
\usepackage{amsmath}

\begin{document}

\[ { \renewcommand{\arraystretch}{2}
\begin{bmatrix}
\dfrac{\partial f}{\partial x}
\\
\dfrac{\partial f}{\partial y}
\end{bmatrix}
}
\]

\end{document}

enter image description here

0
3

The environments of nicematrix have two keys cell-space-top-limit and cell-space-bottom-limit inspired by the parameters cellspacetoplimit and cellspacebottomlimit of cellspace. There is also a key cell-space-limit to fix both parameters.

\documentclass{article}
\usepackage{amsmath}
\usepackage{nicematrix}

\begin{document}

\[
\begin{bNiceMatrix}[cell-space-limits=2pt]
  \dfrac{\partial f}{\partial x}
  \\
  \dfrac{\partial f}{\partial y}
\end{bNiceMatrix}
\]

\end{document}

Output of the above code

1
  • 1
    This works for me exactly how one would expect from standard environments. Underrated answear
    – struct
    Commented Aug 21, 2021 at 16:39
2

The tabstackengine package allows you to set the baselineskip explicitly.

\documentclass{article}
\usepackage{amsmath,tabstackengine}
\TABstackMathstyle{\displaystyle}% NOT NEEDED FOR THIS MWE, BUT USEFUL
\begin{document}
\[
\setstackgap{L}{30pt}
\bracketVectorstack{
  \dfrac{\partial f}{\partial x}
  \\
  \dfrac{\partial f}{\partial y}
}
\qquad
\setstackgap{L}{38pt}
\bracketVectorstack{
  \dfrac{\partial f}{\partial x}
  \\
  \dfrac{\partial f}{\partial y}
}
\]
\end{document}

enter image description here

1

Another solution: load the cellspace package with option [math]. It lets you define a minimal vertical spacing at the top and bottom of cells in columns with specifier prefixed with the letter S (or C if you load siunitx, which already defines an Scolumn type). The [math] option extends this padding to the various matrix environments from amsmath.

Another interesting (and complementary) possibility is the \mfrac command (medium-sized fraction, ~80 % of \displaystyle) from nccmath.

\documentclass{article}
\usepackage{amsmath, nccmath}
\usepackage[math]{cellspace}
\setlength{\cellspacetoplimit}{3pt}
\setlength{\cellspacebottomlimit}{3pt}

\begin{document}

\[ A = \begin{bmatrix}
\dfrac{\partial f}{\partial x} \\
\dfrac{\partial f}{\partial y}
\end{bmatrix} \]

\[ B = \begin{bmatrix}
\mfrac{\partial f}{\partial x} \\
\mfrac{\partial f}{\partial y}
\end{bmatrix} \]

\end{document} 

enter image description here

1

In the following example, I define a new environment +bmatrix using the new LaTeX3 package tabularray. You can also adjust the rowsep in the optional argument.

\documentclass{article}

\usepackage{amsmath}

\usepackage{tabularray}
\usepackage{environ}
\NewEnviron{+bmatrix}[1][2pt]{%
  \hbox{$\left[
  \begin{tblr}[expand=\BODY]{
    rowsep = #1, colsep = 5pt,
    column{1} = {leftsep = 0pt},
    column{Z} = {rightsep = 0pt}, % last column
  }
    \BODY
  \end{tblr}
  \right]$}
}

\begin{document}

\section{Using \texttt{bmatrix} without rowsep}

\[
\begin{bmatrix}
  \dfrac{\partial f}{\partial x} & \dfrac{\partial f}{\partial x}
  \\
  \dfrac{\partial f}{\partial y} & \dfrac{\partial f}{\partial y}
\end{bmatrix}
\]

\section{Using \texttt{+bmatrix} with default \texttt{rowsep=2pt}}

\[
\begin{+bmatrix}
  \dfrac{\partial f}{\partial x} & \dfrac{\partial f}{\partial x}
  \\
  \dfrac{\partial f}{\partial y} & \dfrac{\partial f}{\partial y}
\end{+bmatrix}
\]

\section{Using \texttt{+bmatrix} with \texttt{rowsep=4pt}}

\[
\begin{+bmatrix}[4pt]
  \dfrac{\partial f}{\partial x} & \dfrac{\partial f}{\partial x}
  \\
  \dfrac{\partial f}{\partial y} & \dfrac{\partial f}{\partial y}
\end{+bmatrix}
\]

\end{document}

enter image description here

You must log in to answer this question.

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