[Tex/LaTex] Squares in Matrix

matrices

I would like to write a matrix equation, where the matrix contains equally sized coloured blocks on the diagonal.
Something like:
enter image description here

Does anyone have any idea how to go about this?

Best Answer

The following example calculates the contents of the matrix for the diagonal boxes automatically, given the number of rows. The environments for tables are a little tricky, because each cell is put in a group. Therefore the example first collects the contents of the matrix in a global macro \DiagonalMatrixLines and uses this macro inside the matrix environment. Macro \foreach of package pgffor is used for the loop. (There are many other possibilities.)

The square is determined by the height and depth of the row. The matrix environments are based on the environment array which inserts a special strut \@arstrut to set a minimum height and depth of the row. The additioal white space added by environment array is removed by setting \arraycolsep to zero.

\vdots occupies a little more than one line, but it seems that the matrix with the diagonal boxes should not contain a row with \vdots. Therefore is a matrix with four blocks smaller in height and with five blocks larger. The next example uses the inner part of the left matrix to get the height of the matrix and uses this height to resize the matrix with the diagonal blocks. The vertical middle of a matrix lies on the math axis.Therefore we must move the middle of the matrix to the baseline before resizing.

\documentclass{article}
\usepackage{xcolor}
\usepackage{amsmath}
\usepackage{pgf,pgffor,graphicx}

\makeatletter
\newcommand*{\DiagonalMatrixBlock}{%
  \begingroup
    \setlength{\fboxsep}{0pt}%
    \colorbox{red}{%
     \@arstrut
     \kern\dp\@arstrutbox
     \kern\ht\@arstrutbox
    }%
  \endgroup
}

\newcommand*{\@DiagonalMatrix}[1]{%
  \begingroup
    \setlength{\arraycolsep}{0pt}%
    \global\let\DiagonalMatrixLines\@empty
    \foreach[count=\xi] \x in {1,...,#1} {%
      \ifnum\xi>1 %
        \g@addto@macro\DiagonalMatrixLines{\\}%
      \fi
      \foreach \x in {1,...,\xi} {
        \g@addto@macro\DiagonalMatrixLines{&}%
      }%
      \g@addto@macro\DiagonalMatrixLines{\DiagonalMatrixBlock}%
    }%
  \endgroup
}

\newcommand*{\DiagonalMatrix}[1]{%
  \begingroup
    \setlength{\arraycolsep}{0pt}%
    \@DiagonalMatrix{#1}%
    \begin{pmatrix}\DiagonalMatrixLines\end{pmatrix}%
  \endgroup
}
\newcommand*{\ScaledDiagonalMatrix}[2]{%
  \begingroup
    \sbox0{$\begin{matrix}#2\end{matrix}$}%
    \sbox2{$\vcenter{}$}
    \setlength{\arraycolsep}{0pt}%
    \@DiagonalMatrix{#1}%
    \left(%
      \raisebox{\ht2}{%
        \resizebox{!}{\dimexpr\ht0-\ht2\relax}{%
          \raisebox{-\ht2}{%
            $\begin{matrix}\DiagonalMatrixLines\end{matrix}$%
          }%
        }%
      }%
    \right)%
  \endgroup
}
\makeatother

\begin{document}
\[
  \begin{pmatrix}
    b_1 \\ b_2 \\ \vdots \\ b_n
  \end{pmatrix}
  =
  \DiagonalMatrix{5}
  \begin{pmatrix}
    a_1 \\ a_2 \\ \vdots \\ a_n
  \end{pmatrix}
\]
\[
  \newcommand*{\MatrixB}{b_1 \\ b_2 \\ \vdots \\ b_n}
  \begin{pmatrix}\MatrixB\end{pmatrix}
  =
  \ScaledDiagonalMatrix{8}{\MatrixB}
  \begin{pmatrix}
    a_1 \\ a_2 \\ \vdots \\ a_n
  \end{pmatrix}
\]
\end{document}

Result