Arbitrary permutations of matrix entries
If you want to permute matrix entries, this can be done as follows. Here is a proof of principle, which works. You define a matrix, and save it via
\matrix[matrix of nodes,save cells=A]
{
a & b & c\\
d & e & f\\
g & h & i\\
};
where A
serves an identifier (in case you have several matrices). This matrix can be recast in a permuted form using
\matrix[xshift=3cm,matrix of nodes,declare function={mati(\i,\j)=4-\i;
matj(\i,\j)=\j;},reorder cells=A]
{
& & \\
& & \\
& & \\
};
Here the functions mati(\i,\j)
and matj(\i,\j)
define the mapping of the row index \i
and the column index \j
. In this case at hand, it just reverts the ordering of the rows.
\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{matrix}
\makeatletter
\tikzset{save cells/.style={cells={nodes={execute at begin
node={\ifcsname matrixcellbox#1-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname%
\else%
\expandafter\newbox\csname matrixcellbox#1-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname%
\fi%
\expandafter\expandafter\global\setbox\csname matrixcellbox#1-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname=\hbox\bgroup},
execute at end
node={\egroup%
\expandafter\copy\csname matrixcellbox#1-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname%
}}}},
reorder cells/.style={nodes in empty cells,
cells={nodes={execute at begin
node={
\setbox0=\hbox\bgroup},
execute at end
node={\egroup%
\pgfmathtruncatemacro{\myi}{mati(\the\pgfmatrixcurrentrow,\the\pgfmatrixcurrentcolumn)}%
\pgfmathtruncatemacro{\myj}{matj(\the\pgfmatrixcurrentrow,\the\pgfmatrixcurrentcolumn)}%
%\typeout{(\the\pgfmatrixcurrentrow,\the\pgfmatrixcurrentcolumn)->(\myi,\myj)}%
\expandafter\copy\csname matrixcellbox#1-\myi-\myj\endcsname%
}}}}}
\makeatother
\begin{document}
\begin{tikzpicture}
\matrix[matrix of nodes,save cells=A]
{
a & b & c\\
d & e & f\\
g & h & i\\
};
\matrix[xshift=3cm,matrix of nodes,declare function={mati(\i,\j)=4-\i;
matj(\i,\j)=\j;},reorder cells=A]
{
& & \\
& & \\
& & \\
};
\end{tikzpicture}
\end{document}
At the expense of even more complex style definitions, one can spare the user from having to enter an empty matrix by employing these routines. Of course, one can also make the nodes math. The mapping is also slightly more complex in this example:
\documentclass[tikz,border=3mm]{standalone}
\usepackage{etoolbox}
\usetikzlibrary{matrix}
\newcommand{\CreateEmptyMatrix}[3]{% based on https://tex.stackexchange.com/a/60400
\xdef#3{}%
\foreach \j in {1,...,#1}{
\foreach \i in {1,...,\the\numexpr#2-1} {%
\begingroup\edef\x{\endgroup
\noexpand\gappto\noexpand#3{ {} \&}}\x
}%
\gappto#3{\\}%
}
}
\makeatletter
\tikzset{save cells/.style={cells={nodes={execute at begin
node={\ifcsname matrixcellbox#1-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname%
\else%
\expandafter\newbox\csname matrixcellbox#1-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname%
\fi%
\expandafter\expandafter\global\setbox\csname matrixcellbox#1-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname=\hbox\bgroup},
execute at end
node={\egroup%
\expandafter\copy\csname matrixcellbox#1-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname%
}}},
execute at end matrix={%
\expandafter\xdef\csname matrix@rows@#1\endcsname{\the\pgfmatrixcurrentrow}%
\expandafter\xdef\csname matrix@colss@#1\endcsname{\the\pgfmatrixcurrentcolumn}%
}},
save math cells/.style={cells={nodes={execute at begin
node={\ifcsname matrixcellbox#1-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname%
\else%
\expandafter\newbox\csname matrixcellbox#1-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname%
\fi%
\expandafter\expandafter\global\setbox\csname matrixcellbox#1-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname=\hbox\bgroup$},
execute at end
node={$\egroup%
\expandafter\copy\csname matrixcellbox#1-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname%
}}},
execute at end matrix={%
\expandafter\xdef\csname matrix@rows@#1\endcsname{\the\pgfmatrixcurrentrow}%
\expandafter\xdef\csname matrix@cols@#1\endcsname{\the\pgfmatrixcurrentcolumn}%
}},
reorder cells/.style={/utils/exec=%
\edef\myrows{\csname matrix@rows@#1\endcsname}%
\edef\mycols{\csname matrix@cols@#1\endcsname}%
\CreateEmptyMatrix{\myrows}{\mycols}{\myemptymatrix},
ampersand replacement=\&,
node contents=\myemptymatrix,
nodes in empty cells,
cells={nodes={execute at begin
node={
\setbox0=\hbox\bgroup},
execute at end
node={\egroup%
\edef\myrows{\csname matrix@rows@#1\endcsname}%
\edef\mycols{\csname matrix@cols@#1\endcsname}%
\pgfmathtruncatemacro{\myi}{max(1,min(\myrows,mati(\the\pgfmatrixcurrentrow,\the\pgfmatrixcurrentcolumn)))}%
\pgfmathtruncatemacro{\myj}{max(1,min(\mycols,matj(\the\pgfmatrixcurrentrow,\the\pgfmatrixcurrentcolumn)))}%
%\typeout{(\the\pgfmatrixcurrentrow,\the\pgfmatrixcurrentcolumn)->(\myi,\myj)}%
\expandafter\copy\csname matrixcellbox#1-\myi-\myj\endcsname%
}}}}}
\makeatother
\begin{document}
\begin{tikzpicture}
\matrix[matrix of nodes,save math cells=A]
{
a & b & c\\
d & e & f\\
g & h & i\\
};
\matrix[xshift=3cm,matrix of nodes,
declare function={mati(\i,\j)=4-\i;
matj(\i,\j)=4-\j;},reorder cells=A]
{
};
\end{tikzpicture}
\end{document}
Of course, one may suppress the output of the first matrix, e.g. by shooting it into a box that we never use.
OLDER ANSWER: This effect can be achieved by dialing negative row sep
.
\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{matrix}
\tikzset{swap rows/.style={row sep=-3em,yshift=1em}}
\begin{document}
\begin{tikzpicture}
\matrix[matrix of math nodes]
{
a & b & c\\
d & e & f\\
g & h & i\\
};
\matrix[xshift=3cm,matrix of math nodes,swap rows]
{
a & b & c\\
d & e & f\\
g & h & i\\
};
\end{tikzpicture}
\end{document}
Similar tricks have been used here and here.