[Tex/LaTex] Matrix inside matrix

arraysmath-modematrices

How I can make a matrix inside a matrix as shown in this picture?
enter image description here

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:

enter image description here

Best Answer

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
    \pgf@yc=\pgf@yb \advance\pgf@yc-\pgf@ya
    \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

Same task for another shape

\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
    \pgf@xc=\pgf@xb \advance\pgf@xc-\pgf@xa
    \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
    \advance\pgf@y3pt
  }
  \foregroundpath{
    \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
    \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
    \pgf@xc=\pgf@xb \advance\pgf@xc-\pgf@xa
    \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
    \advance\pgf@y5pt
  }
  \foregroundpath{
    \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
    \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
    \pgf@xc=\pgf@xb \advance\pgf@xc-\pgf@xa
    \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
    \advance\pgf@y-12pt
  }
  \foregroundpath{
    \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
    \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
    \pgf@xc=\pgf@xb \advance\pgf@xc-\pgf@xa
    \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
    \pgf@yc=\pgf@yb \advance\pgf@yc-\pgf@ya
    \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
    \pgf@yc=\pgf@yb \advance\pgf@yc-\pgf@ya
    \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}
Related Question