# Matrix inside matrix

How I can make a matrix inside a matrix as shown in this picture?

Indeed, I want to treat every block as a separate matrix. For example, I want to add braces over and under the second matrix by ‎\underbrace{} or \overbrace{}‎ commands as you see in the picture below:

• As a start, consider reading up on Nested matrices with aligned columns and rows. – Werner Apr 1 '15 at 22:26
• @Werner Thanks, but is't not working for my goal. For example, I want to add a brace under the second matrix by ‎\underbrace{}‎ command. – Qaher Apr 1 '15 at 23:22
• Unfortunately you neglected to add this detail. Please consider adding what you've tried as part of an edit to your original post. – Werner Apr 1 '15 at 23:24
• I suggest you should turn to drawing packages such as TikZ. – Symbol 1 Apr 2 '15 at 1:04

This is a TikZ approach.

## Step 1

First I found that fit library is useful in calculating the bounding box. In the next figure, the brown box does not include bbbbbb_3 because I did not pass (A-2-3) to fit=.

\documentclass[border=9,tikz]{standalone}
\usetikzlibrary{matrix,fit}
\begin{document}
\makeatletter
\begin{tikzpicture}
\matrix(A)[matrix of math nodes]{
a_1 & a_2 & a_3 & aaaaaa_4 \\
b_1 & b_2 & bbbbbb_3 & b_4 \\
c_1 & cccccc_2 & c_3 & c_4 \\
dddddd_1 & d_2 & d_3 & d_4 \\
};
\node[draw=brown,inner sep=0,fit={(A-2-2)(A-3-2)(A-3-3)}]{};
\end{tikzpicture}


## Step 2

Since the brown box is actually a node, I would like to give that node a special shape: A shape of left parenthesis. The code is basically copy from tikzlibrarymatrix.code.tex.

\pgfdeclareshape{left parenthesis}{
\inheritsavedanchors[from=rectangle]\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{center}
\foregroundpath{
\southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
\northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
\pgftransformshift{\pgfpoint{\pgf@xa}{.5\pgf@ya+.5\pgf@yb}}
\pgfnode{rectangle}{center}{$\left(\vcenter{\hrule height\pgf@yc width0pt}\right.$}{leftparenthesis}{\pgfusepath{}}
}
}
\begin{tikzpicture}
\matrix(A)[matrix of math nodes]{
a_1 & a_2 & a_3 & aaaaaa_4 \\
b_1 & b_2 & bbbbbb_3 & b_4 \\
c_1 & cccccc_2 & c_3 & c_4 \\
dddddd_1 & d_2 & d_3 & d_4 \\
};
\node[draw=brown,          inner sep=0,fit={(A-2-2)(A-3-2)(A-3-3)}]{};
\node[red,left parenthesis,inner sep=0,fit={(A-2-2)(A-3-2)(A-3-3)}]{};
\end{tikzpicture}


## Step 2.5

\pgfdeclareshape{below curly bracket}{
\inheritsavedanchors[from=rectangle]\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{center}
\foregroundpath{
\southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
\northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
\pgftransformshift{\pgfpoint{.5\pgf@xa+.5\pgf@xb}{\pgf@ya}}\pgftransformrotate{90}
\pgfnode{rectangle}{center}{$\left\{\vcenter{\hrule height\pgf@xc width0pt}\right.$}{belowcurlybracket}{\pgfusepath{}}
}
}
\begin{tikzpicture}
\matrix(A)[matrix of math nodes]{
a_1 & a_2 & a_3 & aaaaaa_4 \\
b_1 & b_2 & bbbbbb_3 & b_4 \\
c_1 & cccccc_2 & c_3 & c_4 \\
dddddd_1 & d_2 & d_3 & d_4 \\
};
\node[draw=brown,              inner sep=0,fit={(A-2-2)(A-3-2)(A-3-3)}]{};
\node[blue,below curly bracket,inner sep=0,fit={(A-2-2)(A-3-2)(A-3-3)}]{};
\end{tikzpicture}


## Step 3

Remember that everything is node here, so it can be fit= hierarchically.

\begin{tikzpicture}
\matrix(A)[matrix of math nodes]{
a_1 & a_2 & a_3 & aaaaaa_4 \\
b_1 & b_2 & bbbbbb_3 & b_4 \\
c_1 & cccccc_2 & c_3 & c_4 \\
dddddd_1 & d_2 & d_3 & d_4 \\
};
\node[draw=brown,              inner sep=0,fit={(A-2-2)(A-3-2)(A-3-3)}]{};
\node[red,left parenthesis,    inner sep=0,fit={(A-2-2)(A-3-2)(A-3-3)}]{};
\node[blue,below curly bracket,inner sep=0,fit={(A-2-2)(A-3-2)(A-3-3)(leftparenthesis)}]{};
\node[red,left parenthesis,    inner sep=0,fit={(A-2-2)(A-3-2)(A-3-3)(belowcurlybracket)}]{};
\node[blue,below curly bracket,inner sep=0,fit={(A-2-2)(A-3-2)(A-3-3)(leftparenthesis)}]{};
\node[red,left parenthesis,    inner sep=0,fit={(A-2-2)(A-3-2)(A-3-3)(belowcurlybracket)}]{};
\end{tikzpicture}


## Step 4

And then we need to put texts on, so I have to move the text anchor to a suitable place. (In fact I redefine it.) Notice that in this case, bounding box calculation ignores our text. (Which is always true. But usually our text lies completely inside the border because we want so.)

\pgfdeclareshape{above square bracket}{
\inheritsavedanchors[from=rectangle]\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{center}
\anchor{text}{
\southwest
\pgf@xa=\pgf@x
\northeast
\pgf@x=\pgf@xa
}
\foregroundpath{
\southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
\northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
\pgftransformshift{\pgfpoint{.5\pgf@xa+.5\pgf@xb}{\pgf@yb}}\pgftransformrotate{90}
\pgfnode{rectangle}{center}{$\left.\vcenter{\hrule height\pgf@xc width0pt}\right]$}{abovesquarebracket}{}
}
}
\begin{tikzpicture}
\matrix(A)[matrix of math nodes]{
a_1 & a_2 & a_3 & aaaaaa_4 \\
b_1 & b_2 & bbbbbb_3 & b_4 \\
c_1 & cccccc_2 & c_3 & c_4 \\
dddddd_1 & d_2 & d_3 & d_4 \\
};
\node[draw=brown,               inner sep=0,fit={(A-2-2)(A-3-2)(A-3-3)}]{};
\node[teal,above square bracket,inner sep=0,fit={(A-2-2)(A-3-2)(A-3-3)}]{Caption};
\node[red,left parenthesis,     inner sep=0,fit={(A-2-2)(A-3-2)(A-3-3)(abovesquarebracket)}]{};
\node[blue,below curly bracket, inner sep=0,fit={(A-2-2)(A-3-2)(A-3-3)(leftparenthesis)}]{};
\end{tikzpicture}


## Result

\pgfdeclareshape{above curly bracket}{
\inheritsavedanchors[from=rectangle]\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{center}
\anchor{text}{
\southwest
\pgf@xa=\pgf@x
\northeast
\pgf@x=\pgf@xa
}
\foregroundpath{
\southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
\northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
\pgftransformshift{\pgfpoint{.5\pgf@xa+.5\pgf@xb}{\pgf@yb}}\pgftransformrotate{90}
\pgfnode{rectangle}{center}{$\left.\vcenter{\hrule height\pgf@xc width0pt}\right\}$}{abovecurlybracket}{}
}
}
\pgfdeclareshape{below curly bracket}{
\inheritsavedanchors[from=rectangle]\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{center}
\anchor{text}{
\southwest
}
\foregroundpath{
\southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
\northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
\pgftransformshift{\pgfpoint{.5\pgf@xa+.5\pgf@xb}{\pgf@ya}}\pgftransformrotate{90}
\pgfnode{rectangle}{center}{$\left\{\vcenter{\hrule height\pgf@xc width0pt}\right.$}{belowcurlybracket}{}
}
}
\pgfdeclareshape{left square bracket}{
\inheritsavedanchors[from=rectangle]\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{center}
\foregroundpath{
\southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
\northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
\pgftransformshift{\pgfpoint{\pgf@xa}{.5\pgf@ya+.5\pgf@yb}}
\pgfnode{rectangle}{center}{$\left[\vcenter{\hrule height\pgf@yc width0pt}\right.$}{leftsquarebracket}{\pgfusepath{}}
}
}
\pgfdeclareshape{right square bracket}{
\inheritsavedanchors[from=rectangle]\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{center}
\foregroundpath{
\southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
\northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
\pgftransformshift{\pgfpoint{\pgf@xb}{.5\pgf@ya+.5\pgf@yb}}
\pgfnode{rectangle}{center}{$\left.\vcenter{\hrule height\pgf@yc width0pt}\right]$}{rightsquarebracket}{\pgfusepath{}}
}
}

\begin{tikzpicture}
\matrix(A)[matrix of math nodes]{
a_1 & a_2 & a_3 & aaaaaa_4 \\[12pt]
b_1 & b_2 & bbbbbb_3 & b_4 \\
c_1 & cccccc_2 & c_3 & c_4 \\
dddddd_1 & d_2 & d_3 & d_4 \\
};
\node[magenta,left square bracket, inner sep=0,fit={(A-2-2)(A-3-2)(A-4-4)}]{};
\node[magenta,right square bracket,inner sep=0,fit={(A-2-2)(A-3-2)(A-4-4)}]{};
\node[magenta,above curly bracket, inner sep=0,fit={(leftsquarebracket)(rightsquarebracket)}]{This is B};
\node[magenta,below curly bracket, inner sep=0,fit={(leftsquarebracket)(rightsquarebracket)}]{This is also B};
\node[cyan,left square bracket, inner sep=0,fit={(A-1-4)(A-4-1)(belowcurlybracket)}]{};
\node[cyan,right square bracket,inner sep=0,fit={(A-1-4)(A-4-1)(belowcurlybracket)}]{};
\node[cyan,above curly bracket, inner sep=0,fit={(leftsquarebracket)(rightsquarebracket)}]{This is A};
\end{tikzpicture}


I noticed that all the matrix elements were aligned relative to the outer matrix as if the brackets and braces were overlaid on top of original, using pre-existing gaps. So that is precisely what I did.

In the revised version I use Tikz to set markers at the corners and compute the size and location of the sub-matrix. This isn't precise, but will do as long as there aren't any extraordinarily large matrix entries. \vphantom was used instead of \rule for the vertical gaps, and the horizontal gaps are fine empty.

The overbraces and underbraces were easy, but I used an array to align the text over and/or under them.

\documentclass{article}
\usepackage{mathtools}
\usepackage{tikz}

\newlength{\tempwidth}
\newlength{\tempheight}

\newcommand{\Mark}[2]% #1 = node name, #2 = text
{\tikz[remember picture, overlay]%
{\node[anchor=base](#1){$#2$};}}

\begin{document}

\begin{equation*}
f_k(x) = \det
\begin{array}{c}
\textrm{This is $A$}\\
\overbrace{%
\begin{bmatrix}
x& &a&b&c&\cdots&d& \\
\vphantom{\overbrace{\strut}} \\
e& &\Mark{NW}{x}&f&g&\cdots&h\\
i&&j&&&&\vdots\\
&&&&&&k\\
\vdots&&\vdots&&&x&j\\
l&&m&\cdots&n&o&\Mark{SE}{x}\\
\vphantom{\underbrace{\strut}}
\end{bmatrix}}
\end{array}
\end{equation*}

\begin{tikzpicture}[remember picture,overlay]
\pgfextracty{\tempheight}{\pgfpointdiff{\pgfpointanchor{SE}{south}}%
{\pgfpointanchor{NW}{north}}}
\global\tempheight=\tempheight
\pgfextractx{\tempwidth}{\pgfpointdiff{\pgfpointanchor{NW}{west}}%
{\pgfpointanchor{SE}{east}}}
\global\tempwidth=\tempwidth
\path (NW.north west) +(0.5\tempwidth,-0.5\tempheight) node{$\displaystyle \begin{array}{c} \textrm{This is$B$}\\ \overbrace{\underbrace{% \begin{bmatrix} \rule{0pt}{\tempheight}\rule{\tempwidth}{0pt} \end{bmatrix}}}\\ \textrm{This is also B} \end{array}$};
\end{tikzpicture}

\end{document}

• Thanks for your nice answer, but I should change numbers in \rule{}{} command to fit outside matrix with second inside matrix. – Qaher Apr 2 '15 at 7:40
• I could us tikz to calculate some of the sizes, but not all. – John Kormylo Apr 2 '15 at 14:59