2

I'm trying to create an environment for matrices that are divided in four sections, such as the following:

enter image description here

Ideally, I'd like to make it so that it can be used like the following:

M = 
\left(
\begin{croosmatrix}
   \begin{matrix}
      a & b & c & d \\
      e & f & g & h \\
      i & j & k & l 
   \end{matrix} 
      & B \\
   C & D \\
\end{crossmatrix}
\right)

I already know how to achieve such result manually, as decribed in Dividing line in a matrix. Something like the following:

M = 
\left(
\begin{array}{c|c}
   \begin{matrix}
      a & b & c & d \\
      e & f & g & h \\
      i & j & k & l 
   \end{matrix} 
      & B \\
   \hline
   C & D \\
\end{array}
\right)

My question is, how could I make it an environment? In other words, is there a way to programmatically place an \hile between each like on an array? Is it possible to create an environment for such a thing?

Bernard
  • 271,350
  • 1
    I'd recommend just to switch to nicematrix, which supports blocks and lines and much more. –  May 27 '20 at 21:51

3 Answers3

3

You can use nicematrix which constructs the matrix while creating Tikz nodes. You can use these nodes to draw what you want with Tikz.

\documentclass{article}
\usepackage{nicematrix,tikz}

\NewDocumentEnvironment {crossmatrix} { } { \begin{pNiceArray}{cc}[margin] } { \CodeAfter \tikz \draw (2-|1) -- (2-|3) (1-|2) -- ([yshift=1pt]2-|2) ++ (0,-2pt) -- (3-|2) ; \end{pNiceArray} }

\begin{document} $M = \begin{crossmatrix} \begin{matrix} a & b & c & d \ e & f & g & h \ i & j & k & l \end{matrix} & B \ C & D \end{crossmatrix}$ \end{document}

Result of the above code

F. Pantigny
  • 40,250
  • 3
    +1. I would put everything on one \draw command \draw (row-2-|col-1) -- (row-2-|col-3) (row-1-|col-2) -- ([yshift=1pt]row-2-|col-2) ++ (0,-2pt) -- (row-3-|col-2) ;, mostly because, while you are not doing this, your code may be mistaken to nest tikzpictures. –  May 27 '20 at 23:04
  • @ Schrödinger's cat: You're right. I have modified my answer. – F. Pantigny May 28 '20 at 09:29
2

You want to insert to the item of the outer table (\halign) the nested table (\haling). It is not problem if the nested \halign is realized as a macro which reads its parameter in {...}. Then such parameter can include tabs & and \cr used for its inner nested \halign. But if you want to use a macro with separated parameter and not in {...} then the tabs & and \cr in such parameter are interpreted during reading of the parameter as tabs for outer \halign.

The nested \begin{matrix}..&..&.\end{matrix} reads its parameter terminated by \end{matrix} (no in {...}), so tabs & used here are interpreted by the outer \halign. Of course, you can hide these tabs by {\begin{mattrix}..&..&.\end{matrix}} but the LaTeX logic of tagging tables and using nested LaTeX environments is lost.

The following example shows the problem in native TeX language:

\def\a#1{\vbox{\halign{##&##\cr#1\cr}}}

\halign{X#Y&Z#W\cr    ..\a{b&c}..& d\cr}

Works, because the b&c is read inside {}, so the & here is not interpreted by the outer \halign.

\def\a[#1]{\vbox{\halign{##&##\cr#1\cr}}}

\halign{X#Y&Z#W\cr    ..\a[b&c]..& d\cr}

Doesn't work because when b& is read into the parameter then TeX interprets & as the tab for outer \halign and the reading of the parameter continues by Y followed by \endtemplate which is prohibited read it to a parameter.

\def\a[#1]{\vbox{\halign{##&##\cr#1\cr}}}

\halign{X#Y&Z#W\cr    ..{\a[b&c]}..& d\cr}

Works.

wipet
  • 74,238
1

The problem is the syntax. Here I propose to specify the parts as arguments to the environment.

\documentclass{article}
\usepackage{amsmath}

\newenvironment{crossmatrix}[3]
 {
  \left(
  \def\crossmatrixfinal{&#1\\\hline#2&#3}
  \begin{array}{@{}c|c@{}}
  \begin{matrix}
 }
 {
  \end{matrix}
  \crossmatrixfinal
  \end{array}
  \right)
 }

\begin{document}

\[
\begin{crossmatrix}{B}{C}{D}
  a & b & c & d \\
  e & f & g & h \\
  i & j & k & l 
\end{crossmatrix}
\]

\end{document}

enter image description here

egreg
  • 1,121,712