[Tex/LaTex] How to label different rows or columns of a matrix using braces

bracketslabelsmatrices

I have a matrix enclosed in brackets [ ] (or (), or {}, or |'s, or ||'s):

- a b c d -
| e f g h |
| i j k l |
- m n o p -

which I want to label like so:

           R
         |---|
  -- - a b c d -
 A|  | e f g h |
  -- | i j k l |
     - m n o p -  

Where the dashes by the labels are meant to be giant {'s as in this picture:
alt text
How can I do this?


Although two answers have been provided that work to an extent, I've added a bounty because I'd like to see if anyone has, or can come up with, a neat, robust solution.

Best Answer

The following solution uses TikZ, but a minimal amount of hacks:

\usepackage{tikz}
\usetikzlibrary{matrix,decorations.pathreplacing}

\begin{tikzpicture}[decoration=brace]
    \matrix (m) [matrix of math nodes,left delimiter=[,right delimiter={]}] {
        a & b & c & d \\
        e & f & g & h \\
        i & j & k & l \\
        m & n & o & p \\
    };
    \draw[decorate,transform canvas={xshift=-1.5em},thick] (m-3-1.south west) -- node[left=2pt] {$A$} (m-1-1.north west);
    \draw[decorate,transform canvas={yshift=0.5em},thick] (m-1-2.north west) -- node[above=2pt] {$R$} (m-1-4.north east);
\end{tikzpicture}

First two tikz libraries are loaded (this only needs to be done once). In the tikzpicture environment a matrix called m is defined. The delimiters can be changed to anything that is acceptable after \left in math mode. Entries of the matrix can be reference by name-row-column (where in this case the name is m). I found good looking shifts (i.e. the distances between brace and matrix entry) by trail-and-error; you might have to change them. Also you might want to try removing the thick parameter.


I tried wrapping the whole stuff in nice commands. Unfortunately I only succeeded partially, because I do not know how to handle the & in the matrix without LaTeX complaining about "misplaced alignment tab character". I tweaked the spacing in the following tikz styles a bit to make the matrix look more like the usual ones. Maybe there are better ways to do this (are all the lengths the (usual) matrix environment used accessible somehow?).

Anyway, on to the commands. Put the following wall of code somewhere near the beginning of the document:

% Load TikZ
\usepackage{tikz}
\usetikzlibrary{matrix,decorations.pathreplacing,calc}

% Set various styles for the matrices and braces. It might pay off to fiddle around with the values a little bit
\pgfkeys{tikz/mymatrixenv/.style={decoration=brace,every left delimiter/.style={xshift=3pt},every right delimiter/.style={xshift=-3pt}}}
\pgfkeys{tikz/mymatrix/.style={matrix of math nodes,left delimiter=[,right delimiter={]},inner sep=2pt,column sep=1em,row sep=0.5em,nodes={inner sep=0pt}}}
\pgfkeys{tikz/mymatrixbrace/.style={decorate,thick}}
\newcommand\mymatrixbraceoffseth{0.5em}
\newcommand\mymatrixbraceoffsetv{0.2em}

% Now the commands to produce the braces. (I'll explain below how to use them.)
\newcommand*\mymatrixbraceright[4][m]{
    \draw[mymatrixbrace] ($(#1.north west)!(#1-#3-1.south west)!(#1.south west)-(\mymatrixbraceoffseth,0)$)
        -- node[left=2pt] {#4} 
        ($(#1.north west)!(#1-#2-1.north west)!(#1.south west)-(\mymatrixbraceoffseth,0)$);
}
\newcommand*\mymatrixbraceleft[4][m]{
    \draw[mymatrixbrace] ($(#1.north east)!(#1-#2-1.north east)!(#1.south east)+(\mymatrixbraceoffseth,0)$)
        -- node[right=2pt] {#4} 
        ($(#1.north east)!(#1-#3-1.south east)!(#1.south east)+(\mymatrixbraceoffseth,0)$);
}
\newcommand*\mymatrixbracetop[4][m]{
    \draw[mymatrixbrace] ($(#1.north west)!(#1-1-#2.north west)!(#1.north east)+(0,\mymatrixbraceoffsetv)$)
        -- node[above=2pt] {#4} 
        ($(#1.north west)!(#1-1-#3.north east)!(#1.north east)+(0,\mymatrixbraceoffsetv)$);
}
\newcommand*\mymatrixbracebottom[4][m]{
    \draw[mymatrixbrace] ($(#1.south west)!(#1-1-#3.south east)!(#1.south east)-(0,\mymatrixbraceoffsetv)$)
        -- node[below=2pt] {#4} 
        ($(#1.south west)!(#1-1-#2.south west)!(#1.south east)-(0,\mymatrixbraceoffsetv)$);
}

After that, you can simply use the following code to produce your example:

\[
\begin{tikzpicture}[mymatrixenv]
    \matrix[mymatrix] (m)  {
        a & b & c & d \\
        e & f & g & h \\
        i & j & k & l \\
        m & n & o & p \\
    };
    \mymatrixbraceright{1}{3}{$A$}
    \mymatrixbracetop{2}{4}{$R$}
\end{tikzpicture}
\]

The matrix definition remained pretty much the same as before, except that all the styles needed are now stored in mymatrixenv and mymatrix. No need to repeat them for every matrix!

The braces are produced with \mymatrixbraceright, \mymatrixbracetop, \mymatrixbraceleft and \mymatrixbracebottom for right, top, left and bottom braces respectively. The commands all work the same way: They have three mandatory commands for starting and ending position of the brace (in "natural" order) and the label. Additionally they have one optional argument for specifying the name of the matrix (it defaults to m). So, if you want a brace on the left of matrix foo going from the row 3 to row 417 and with label $415$ rows!, you use

\mymatrixbraceleft[foo]{3}{417}{$415$ rows!}
Related Question