% Copyright 2006 by Till Tantau
%
% This file may be distributed and/or modified
%
% 1. under the LaTeX Project Public License and/or
% 2. under the GNU Free Documentation License.
%
% See the file doc/generic/pgf/licenses/LICENSE for more details.


\section{Matrices}

\label{section-base-matrices}

\begin{pgfmodule}{matrix}
  The present section documents the commands of this module.
\end{pgfmodule}

\subsection{Overview}

Matrices are a mechanism for aligning several so-called cell pictures
horizontally and vertically. The resulting alignment is placed in a
normal node and the command for creating matrices, |\pgfmatrix|, takes
options very similar to the |\pgfnode| command.

In the following, the basic idea behind the alignment mechanism is
explained first. Then the command |\pgfmatrix| is explained. At the
end of the section, additional ways of modifying the width of columns
and rows are discussed.


\subsection{Cell Pictures and Their Alignment}

A matrix consists of rows of \emph{cells}. Cells are separated using
the special command |\pgfmatrixnextcell|, rows are ended using the
command |\pgfmatrixendrow| (the command |\\| is set up to mean the same
as |\pgfmatrixendrow| by default). Each cell contains a \emph{cell
  picture}, although cell pictures are not complete pictures as they
lack layers. However, each cell picture has its own bounding box like a
normal picture does. These bounding boxes are important for the
alignment as explained in the following.

Each cell picture will have an origin somewhere in the picture (or
even outside the picture). The position of these origins are important
for the alignment: On each row the origins will be on the same
horizontal line and for each column the origins will also be on the
same vertical line. These two requirements mean that the cell pictures
may need to be shifted around so that the origins wind up on the same
lines. The top of a row is given by the top of the cell picture whose
bounding box's maximum $y$-position is largest. Similarly, the bottom
of a row is given by the bottom of the cell picture whose bounding
box's minimum $y$-position is the most negative. Similarly, the left
end of a row is given by the left end of the cell whose bounding box's
$x$-position is the most negative; and similarly for the right end of
a row.

\begin{codeexample}[]
\begin{tikzpicture}[x=3mm,y=3mm,fill=blue!50]
  \def\atorig#1{\node[black] at (0,0) {\tiny #1};}

  \pgfmatrix{rectangle}{center}{mymatrix}
    {\pgfusepath{}}{\pgfpointorigin}{}
    {
      \fill (0,-3)  rectangle (1,1);\atorig1 \pgfmatrixnextcell
      \fill (-1,0)  rectangle (1,1);\atorig2 \pgfmatrixnextcell
      \fill (-1,-2) rectangle (0,0);\atorig3 \pgfmatrixnextcell
      \fill (-1,-1) rectangle (0,3);\atorig4 \\
      \fill (-1,0)  rectangle (4,1);\atorig5 \pgfmatrixnextcell
      \fill (0,-1)  rectangle (1,1);\atorig6 \pgfmatrixnextcell
      \fill (0,0)   rectangle (1,4);\atorig7 \pgfmatrixnextcell
      \fill (-1,-1) rectangle (0,0);\atorig8 \\
    }
\end{tikzpicture}
\end{codeexample}


\subsection{The Matrix Command}

All matrices are typeset using the following command:

\begin{command}{\pgfmatrix\marg{shape}\marg{anchor}\marg{name}%
    \marg{usage}\marg{shift}\marg{pre-code}\marg{matrix cells}}

  This command creates a node that contains a matrix. The name of the
  node is \meta{name}, its shape is \meta{shape} and the node is
  anchored at \meta{anchor}.

  The \meta{matrix cell} parameter contains the cells of the
  matrix. In each cell drawing commands may be given, which create a
  so-called cell picture. For each cell picture a bounding box is
  computed and the cells are aligned according to the rules outlined
  in the previous section.

  The resulting matrix is used as the |text| box of the node. As for a
  normal node, the \meta{usage} commands are applied, so that the
  path(s) of the resulting node is (are) stroked or filled or whatever.

  \medskip
  \textbf{Specifying the cells and rows.\ }
  Even though this command uses |\halign| internally, there are two
  special rules for indicating cells:
  \begin{enumerate}
  \item Cells in the same row must be separated using the macro
    |\pgfmatrixnextcell| rather than |&|. Using |&| will result in an
    error message.

    However, you can make |&| an active character and have it expand
    to |\pgfmatrixnextcell|. This way, it will ``look'' as if |&| is
    used.
  \item Rows are ended using the command |\pgfmatrixendrow|, but |\\|
    is set up to mean the same by default. However, some environments
    like |{minipage}| redefine |\\|, so it is good to have
    |\pgfmatrixendrow| as a ``fallback.''
  \item Every row \emph{including the last row} must be ended using
    the command |\\| or |\pgfmatrixendrow|.
  \end{enumerate}

  Both |\pgfmatrixnextcell| and |\pgfmatrixendrow| (and, thus, also
  |\\|) take an optional argument as explained in the
  Section~\ref{section-matrix-spacing}

\begin{codeexample}[]
\begin{tikzpicture}
  \pgfmatrix{rectangle}{center}{mymatrix}
    {\pgfusepath{}}{\pgfpointorigin}{}
    {
      \node {a}; \pgfmatrixnextcell \node {b}; \pgfmatrixendrow
      \node {c}; \pgfmatrixnextcell \node {d}; \pgfmatrixendrow
    }
\end{tikzpicture}
\end{codeexample}

  \medskip
  \textbf{Anchoring matrices at nodes inside the matrix.\ }
  The parameter \meta{shift} is an additional negative shift for the
  node. Normally, such a shift could be given beforehand (that is, the
  shift could be preapplied to the current transformation
  matrix). However, when \meta{shift} is evaluated, you can refer to
  \emph{temporary} positions of nodes inside the matrix. In detail,
  the following happens: When the matrix has been typeset, all nodes
  in the matrix temporarily get assigned their positions in the matrix
  box. The origin of this coordinate system is at the left baseline
  end of the matrix box, which corresponds to the |text| anchor. The
  position \meta{shift} is then interpreted inside this coordinate
  system and then used for shifting.

  This allows you to use the parameter \meta{shift} in the following
  way: If you use |text| as the \meta{anchor} and specify
  |\pgfpointanchor{inner node}{some anchor}| for the parameter
  \meta{shift}, where |inner node| is a node that
  is created in the matrix, then the whole matrix will be shifted such
  that |inner node.some anchor| lies at the origin of the whole
  picture.

  \medskip
  \textbf{Rotations and scaling.\ }
  The matrix node is never rotated or shifted, because the current
  coordinate transformation matrix is reset (except for the
  translational part) at the beginning of |\pgfmatrix|. This is
  intentional and will not change in the future. If you need to rotate
  the matrix, you must install an appropriate canvas transformation
  yourself.

  However, nodes and stuff inside the cell pictures can be rotated and
  scaled normally.

  \medskip
  \textbf{Callbacks.\ }
  At the beginning and at the end of each cell the special macros
  |\pgfmatrixbegincode|, |\pgfmatrixendcode| and possibly
  |\pgfmatrixemptycode| are called. The effect is explained in
  Section~\ref{section-matrix-callbacks}.

  \medskip
  \textbf{Executing extra code.\ }
  The parameter \meta{pre-code} is executed at the beginning of the
  outermost \TeX-group enclosing the matrix node. It is inside this
  \TeX-group, but outside the matrix itself. It can be used
  for different purposes:
  \begin{enumerate}
  \item It can be used to simplify the next cell macro. For example,
    saying |\let\&=\pgfmatrixnextcell| allows you to use |\&| instead
    of |\pgfmatrixnextcell|. You can also set the catcode of |&| to
    active.
  \item It can be used to issue an |\aftergroup| command. This allows
    you to regain control after the |\pgfmatrix| command. (If you do
    not know the |\aftergroup| command, you are probably blessed with
    a simple and happy life.)
  \end{enumerate}

  \medskip
  \textbf{Special considerations concerning macro expansion.\ }
  As said before, the matrix is typeset using |\halign|
  internally. This command does a lot of strange and magic things like
  expanding the first macro of every cell in a most unusual
  manner. Here are some effects you may wish to be aware of:
  \begin{itemize}
  \item It is not necessary to actually mention |\pgfmatrixnextcell|
    or |\pgfmatrixendrow| inside the \meta{matrix cells}. It suffices
    that the  macros inside \meta{matrix cells} expand to these macros
    sooner or later.
  \item In particular, you can define clever macros that insert
    columns and rows as needed for special effects.
  \end{itemize}
\end{command}


\subsection{Row and Column Spacing}
\label{section-matrix-spacing}

It is possible to control the space between columns and rows rather
detailedly. Two commands are important for the row spacing and two
commands for the column spacing.

\begin{command}{\pgfsetmatrixcolumnsep\marg{sep list}}
  This macro sets the default separation list for columns. The details of the
  format of this list are explained in the description of the next command.
\end{command}

\begin{command}{\pgfmatrixnextcell\opt{\oarg{additional sep list}}}
  This command has two purposes: First, it is used to separate
  cells. Second, by providing the optional argument \meta{additional
    sep list} you can modify the spacing between the columns that are
  separated by this command.

  The optional \meta{additional sep list} may only be provided when
  the |\pgfmatrixnextcell| command starts a new column. Normally, this
  will only be the case in the first row, but sometimes a later row
  has more elements than the first row. In this case, the
  |\pgfmatrixnextcell| commands that start the new columns in the
  later row may also have the optional argument. Once a column has
  been started, subsequent uses of this optional argument for the
  column have no effect.

  To determine the space between the two columns that are separated by
  |\pgfmatrixnextcell|, the following algorithm is executed:
  \begin{enumerate}
  \item Both the default separation list (as set up by
    |\pgfsetmatrixcolumnsep|) and the \meta{additional sep list} are
    processed, in this order. If the \meta{additional sep list}
    argument is missing, only the default separation list is
    processed.
  \item Both lists may contain dimensions, separated by commas, as
    well as occurrences of the keywords |between origins| and
    |between borders|.
  \item All dimensions occurring in either list are added together to
    arrive at a dimension $d$.
  \item The last occurrence of either of the keywords is located. If
    neither keyword is present, we proceed as if |between borders|
    were present.
  \end{enumerate}
  At the end of the algorithm, a dimension $d$ has been computed and
  one of the two \emph{modes} |between borders| and |between origins|
  has been determined. Depending on which mode has been determined,
  the following happens:
  \begin{itemize}
  \item For the |between borders| mode, an additional horizontal space
    of $d$ is added between the two columns. Note that $d$ may be
    negative.
  \item For the |between origins| mode, the spacing between the two
    columns is computed differently: Recall that the origins of the
    cell pictures in both pictures lie on two vertical lines. The
    spacing between the two columns is set up such that the horizontal
    distance between these two lines is exactly $d$.

    This mode may only be used between columns \emph{already
      introduced in the first row}.
  \end{itemize}
  All of the above rules boil down to the following effects:
  \begin{itemize}
  \item A default spacing between columns should be set up using
    |\pgfsetmatrixcolumnsep|. For example, you might say
    |\pgfsetmatrixcolumnsep{5pt}| to have columns spaced apart by
    |5pt|. You could say
\begin{verbatim}
\pgfsetmatrixcolumnsep{1cm,between origins}
\end{verbatim}
    to specify that horizontal space between the origins of cell
    pictures in adjacent columns should be 1cm by default --
    regardless of the actual size of the cell pictures.
  \item You can now use the optional argument of |\pgfmatrixnextcell|
    to locally overrule the spacing between two columns. By saying
    |\pgfmatrixnextcell[5pt]| you \emph{add} 5pt to the space between
    of the two columns, regardless of the mode.

    You can also (locally) change the spacing mode for these two
    columns. For example, even if the normal spacing mode is
    |between origins|, you can say
\begin{verbatim}
\pgfmatrixnextcell[5pt,between borders]
\end{verbatim}
    to locally change the mode for these columns to
    |between borders|.
  \end{itemize}

    \begin{codeexample}[]
\begin{tikzpicture}[every node/.style=draw]
  \pgfsetmatrixcolumnsep{1mm}
  \pgfmatrix{rectangle}{center}{mymatrix}
    {\pgfusepath{}}{\pgfpointorigin}{\let\&=\pgfmatrixnextcell}
  {
    \node {8}; \&[2mm] \node{1}; \&[-1mm] \node {6}; \\
    \node {3}; \&      \node{5}; \&       \node {7}; \\
    \node {4}; \&      \node{9}; \&       \node {2}; \\
  }
\end{tikzpicture}
    \end{codeexample}
    \begin{codeexample}[]
\begin{tikzpicture}[every node/.style=draw]
  \pgfsetmatrixcolumnsep{1mm}
  \pgfmatrix{rectangle}{center}{mymatrix}
    {\pgfusepath{}}{\pgfpointorigin}{\let\&=\pgfmatrixnextcell}
  {
    \node {8}; \&[2mm] \node(a){1}; \&[1cm,between origins] \node(b){6}; \\
    \node {3}; \&      \node   {5}; \&                      \node   {7}; \\
    \node {4}; \&      \node   {9}; \&                      \node   {2}; \\
  }
  \draw [<->,red,thick,every node/.style=] (a.center) -- (b.center)
        node [above,midway] {11mm};
\end{tikzpicture}
    \end{codeexample}
    \begin{codeexample}[]
\begin{tikzpicture}[every node/.style=draw]
  \pgfsetmatrixcolumnsep{1cm,between origins}
  \pgfmatrix{rectangle}{center}{mymatrix}
    {\pgfusepath{}}{\pgfpointorigin}{\let\&=\pgfmatrixnextcell}
  {
    \node (a) {8}; \& \node (b) {1}; \&[between borders] \node (c) {6}; \\
    \node     {3}; \& \node     {5}; \&                  \node     {7}; \\
    \node     {4}; \& \node     {9}; \&                  \node     {2}; \\
  }
  \begin{scope}[every node/.style=]
    \draw [<->,red,thick] (a.center) -- (b.center) node [above,midway] {10mm};
    \draw [<->,red,thick] (b.east) -- (c.west) node [above,midway]
    {10mm};
  \end{scope}
\end{tikzpicture}
    \end{codeexample}
\end{command}

The mechanism for the between-row-spacing is the same, only the
commands are called differently.


\begin{command}{\pgfsetmatrixrowsep\marg{sep list}}
  This macro sets the default separation list for rows.
\end{command}



\begin{command}{\pgfmatrixendrow\opt{\oarg{additional sep list}}}
  This command ends a line. The optional \meta{additional sep list} is
  used to determine the spacing between the row being ended and the
  next row. The modes and the computation of $d$ is done in the same
  way as for columns. For the last row the optional argument has no
  effect.

  Inside matrices (and only there) the command |\\| is set up to mean
  the same as this command.
\end{command}


\subsection{Callbacks}
\label{section-matrix-callbacks}

There are three macros that get called at the beginning and end of
cells. By redefining these macros, which are empty by default, you can
change the appearance of cells in a very general manner.

\begin{command}{\pgfmatrixemptycode}
  This macro is executed for empty cells. This means that \pgfname\
  uses some macro magic to determine whether a cell is empty (it
  immediately ends with |\pgfmatrixemptycode| or |\pgfmatrixendrow|)
  and, if so, put this macro inside the cell.
  \begin{codeexample}[]
\begin{tikzpicture}
  \def\pgfmatrixemptycode{\node{empty};}
  \pgfmatrix{rectangle}{center}{mymatrix}
    {\pgfusepath{}}{\pgfpointorigin}{\let\&=\pgfmatrixnextcell}
  {
    \node {a}; \&           \& \node {b}; \\
               \& \node{c}; \& \node {d}; \& \\
  }
\end{tikzpicture}
  \end{codeexample}
  As can be seen, the macro is not executed for empty cells at the end
  of row when columns are added only later on.
\end{command}


\begin{command}{\pgfmatrixbegincode}
  This macro is executed at the beginning of non-empty
  cells. Correspondingly, |\pgfmatrixendcode| is added at
  the end of every non-empty cell.
  \begin{codeexample}[]
\begin{tikzpicture}
  \def\pgfmatrixbegincode{\node[draw]\bgroup}
  \def\pgfmatrixendcode{\egroup;}
  \pgfmatrix{rectangle}{center}{mymatrix}
    {\pgfusepath{}}{\pgfpointorigin}{\let\&=\pgfmatrixnextcell}
  {
    a \& b \& c \\
    d \&   \& e \\
  }
\end{tikzpicture}
  \end{codeexample}
  Note that between |\pgfmatrixbegincode| and |\pgfmatrixendcode|
  there will \emph{not} only be the contents of the cell. Rather,
  \pgfname\ will add some (invisible) commands for book-keeping
  purposes that involve |\let| and |\gdef|. In particular, it is not a
  good idea to have |\pgfmatrixbegincode| end with |\csname| and
  |\pgfmatrixendcode| start with |\endcsname|.
\end{command}

\begin{command}{\pgfmatrixendcode}
  See the explanation above.
\end{command}


The following two counters allow you to access the current row and
current column in a callback:

\begin{command}{\pgfmatrixcurrentrow}
  This counter stores the current row of the current cell of the
  matrix. Do not even think about changing this counter.
\end{command}

\begin{command}{\pgfmatrixcurrentcolumn}
  This counter stores the current column of the current cell of the
  matrix.
\end{command}

%%% Local Variables:
%%% mode: latex
%%% TeX-master: "pgfmanual"
%%% End:
