I'm trying to figure out a TiKZ
-based solution to this problem involving arrows between matrix rows. To this end, I would like to at least be able to make a matrix of math nodes
simulate the behaviour of the matrix
environment from amsmath
.
I have encountered several problems in doing so. One of them is the appearance of the matrices themselves and their relation to the surrounding text. Consider the following example:
\documentclass{article}
\usepackage{amsmath,tikz}
\usetikzlibrary{matrix}
\newlength\mtxrowsep \setlength\mtxrowsep{2ex}
\newlength\mtxcolsep \setlength\mtxcolsep{\arraycolsep}
\begin{document}
\begin{gather*}
4 \times
\left[\begin{matrix} a & b \\ c & d \end{matrix}\right]
\qquad
4 \times
\left[\begin{tikzpicture}
\matrix [matrix of math nodes, ampersand replacement=\&,
inner sep=0pt, column sep=\mtxcolsep, row sep=\mtxrowsep]
{ a \& b \\ c \& d \\ };
\end{tikzpicture}\right]
\qquad
4 \times
\left[\begin{minipage}{1.7em}
{}\hfill\begin{tikzpicture}
\matrix [matrix of math nodes, ampersand replacement=\&,
inner sep=0pt, column sep=\mtxcolsep, row sep=\mtxrowsep]
{ a \& b \\ c \& d \\ };
\end{tikzpicture}\hfill{}
\end{minipage}\right]
\end{gather*}
\end{document}
This produces the following output:
The genuine amsmath
matrix is on the left. The matrix in the middle suffers from the fact that the matrix of math nodes
in the tikzpicture
environment is apparently sitting on top of the baseline of the surrounding math. The matrix on the right is properly aligned because it is sitting inside of a minipage
, whose width was manually specified. (Not pictured is anything using left delimiter
or right delimiter
, which has spacing issues of its own and suffers from the same vertical alignment issues.)
Main questions.
-
Is there any way native to
tikz
to change the vertical alignment of thetikzpicture
for the matrix in the middle? (I didn't find anything whilst scanning through the manual…) -
Is there any way to extract the width of an image automatically, to allow automatic resizing of the
minipage
for the matrix on the right?
Best Answer
Okay, here's my first attempt. It needs a little tweaking with spacing either side, and I've only tested it with the 2x2 matrix given and without any font size changes, so some of the choices for lengths might be amiss.
The vertical centring is handled by setting the
baseline
option on the enclosingtikzpicture
. We want the actual centre of the matrix to be a bit above the baseline (about the middle of an=
, I guess). Trial and error gave me a height of.7ex
. Next is the delimiters. TikZ can handle them itself, so I figured it best to let it deal with them rather than putting stuff in boxes or minipages (the node text is already in boxes and so forth so putting in more seems overkill). I found the delimiters to be vertically a little off, so I shifted them down a point, and also a little far out. I didn't want to touch theinner sep
as that changes both vertical and horizontal, so I simply shifted them in a little. These are theevery (left|right|) delimiter
styles. I wanted a littleinner sep
on the matrix itself but not on the entries themselves. I also adjusted the row and column separations a little to better match the AMS styles.Next was the ampersand. I'm a little wary of this, but what I do is to change it to an active character. It checks to see if it is inside a TikZ matrix. If it is, then it produces
\pgfmatrixnextcell
and if not, it produces the old ampersand. This could be made a little more robust by only checking for if we're in one of our special TikZ matrices. I don't know if this is a good solution or not.After that, it's simply a matter of wrapping it all up in an environment.
Let's start with the result. In each row, the first is a
tikzpicture
, the second is the same but wrapped in to an environment, the third is the AMS original.And now the code:
(The
\foreach
loops are just to save me cut-and-pasting a lot.)