6

I am trying to display sparse matrices like chessboards, where white places indicates 0 entries and black ones non-zero entries (in this case matrices are boolean so every non-zero entry is a one entry), but I can't find a proper way.

Because I am looking to show more than one matrix (more in detail, I have to show matrix A and its power), I will have to print more than one on the same page and specify their layout, like figures.

For example, given this matrix as input:

| 0 | 1 | 0 |
| 1 | 0 | 1 |
| 0 | 1 | 0 |

I would expect such output:

enter image description here

6

With TikZ this is rather straightforward.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}
\begin{tikzpicture}[0/.style={draw,ultra thin},1/.style={0,fill=black}]
 \matrix[matrix of nodes,cells={minimum size=1.5em,anchor=center}]
 {|[0]| & |[1]| & |[0]| \\
 |[1]| & |[0]| & |[1]|\\
 |[0]| & |[1]| & |[0]|\\
 };
\end{tikzpicture}
\end{document}

enter image description here

If you have a simple pattern as this one, you could also do

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}
\begin{tikzpicture}[my cell/.style={/utils/exec={%
 \pgfmathtruncatemacro{\itest}{mod(\the\pgfmatrixcurrentrow+\the\pgfmatrixcurrentcolumn,2)}
 \ifnum\itest=1
 \pgfkeysalso{/tikz/fill=black}
 \fi}}]
 \matrix[matrix of nodes,nodes in empty cells,
 nodes={minimum size=1.5em,anchor=center,draw,ultra thin,my cell}]
 { &  &  \\
  &  & \\
  &  & \\
 };
\end{tikzpicture}
\end{document}

An addendum, just for fun. It is rather similar to @egreg's nice answer, in fact \sparsezero, \sparseone and the name of the environment are just stolen from there. The difference is that instead of making 0 and 1 active characters collcell is employed, which is also hacky but arguably less violent. It defines a new column type that just employs a macro. However, extending the entries to larger values will be as easy to add a few \ors to the \ifcase, so I feel that this may be easier to customize than egreg's nice solution this is conceptually building on.

\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{array}
\usepackage{collcell}
\newlength{\sparsesize}
\setlength{\sparsesize}{12pt}
\newcommand{\sparsezero}{%
  \begingroup
  \setlength{\fboxsep}{-0.2pt}%
  \setlength{\fboxrule}{0.2pt}%
  \fbox{\hspace{\sparsesize}\rule{0pt}{\sparsesize}}%
  \endgroup
}
\newcommand{\sparseone}{\rule{\sparsesize}{\sparsesize}}
\newcommand{\sparseentry}[1]{\ifcase#1
\sparsezero
\or
\sparseone
\fi}
\newcolumntype{F}{>{\collectcell\sparseentry}c<{\endcollectcell}}
\newenvironment{sparsematrix}
 {%
  \renewcommand{\arraycolsep}{0pt}%
 \renewcommand{\arraystretch}{0}%
  \begin{array}{*{20}{F}}%
 }
 {\end{array}}
\begin{document}
\[
\begin{sparsematrix}
0 & 1 & 0 \\
1 & 0 & 1 \\
0 & 1 & 0 \\
\end{sparsematrix}=\begin{pmatrix}
0 & 1 & 0 \\
1 & 0 & 1 \\
0 & 1 & 0 \\
\end{pmatrix}
\]
\end{document}
| improve this answer | |
8

With a fairly natural syntax:

\documentclass{article}
\usepackage{amsmath}

\newlength{\sparsesize}
\setlength{\sparsesize}{12pt}

\newcommand{\sparsezero}{%
  \begingroup
  \setlength{\fboxsep}{-0.2pt}%
  \setlength{\fboxrule}{0.2pt}%
  \fbox{\hspace{\sparsesize}\rule{0pt}{\sparsesize}}%
  \endgroup
}
\newcommand{\sparseone}{\rule{\sparsesize}{\sparsesize}}
\newcommand{\activate}[2]{%
  \begingroup\lccode`~=`#1\lowercase{\endgroup\let~}#2%
  \mathcode`#1="8000
}

\newenvironment{sparsematrix}
 {%
  \renewcommand{\arraystretch}{0}%
  \setlength{\arraycolsep}{0pt}%
  \activate{0}{\sparsezero}\activate{1}{\sparseone}%
  \begin{matrix}%
 }
 {\end{matrix}}

\begin{document}

\[
\begin{pmatrix}
0 & 1 & 0 \\
1 & 0 & 1 \\
0 & 1 & 0
\end{pmatrix}
=
\begin{sparsematrix}
0 & 1 & 0 \\
1 & 0 & 1 \\
0 & 1 & 0
\end{sparsematrix}
\]

\end{document}

enter image description here

For general matrices with integer coefficients it's a bit more difficult.

\documentclass{article}
\usepackage{amsmath,xparse}

\newlength{\sparsesize}
\setlength{\sparsesize}{12pt}
\newcommand{\sparsezero}{%
  \begingroup
  \setlength{\fboxsep}{-0.2pt}%
  \setlength{\fboxrule}{0.2pt}%
  \fbox{\hspace{\sparsesize}\rule{0pt}{\sparsesize}}%
  \endgroup
}
\newcommand{\sparseone}{\rule{\sparsesize}{\sparsesize}}

\ExplSyntaxOn
\NewDocumentEnvironment{sparsematrix}{b}
 {
  \renewcommand{\arraystretch}{0}%
  \setlength{\arraycolsep}{0pt}%
  {% make a subformula
   \begin{matrix}
   \eagleone_sparsematrix:n { #1 }
   \end{matrix}
  }
 }{}

\seq_new:N \l__eagleone_sparsematrix_rows_seq
\seq_new:N \l__eagleone_sparsematrix_row_in_seq
\seq_new:N \l__eagleone_sparsematrix_row_out_seq

\cs_new_protected:Nn \eagleone_sparsematrix:n
 {
  \seq_set_split:Nnn \l__eagleone_sparsematrix_rows_seq { \\ } { #1 }
  \seq_map_function:NN \l__eagleone_sparsematrix_rows_seq \__eagleone_sparsematrix_row:n
 }
\cs_new_protected:Nn \__eagleone_sparsematrix_row:n
 {
  \seq_set_split:Nnn \l__eagleone_sparsematrix_row_in_seq { & } { #1 }
  \seq_map_inline:Nn \l__eagleone_sparsematrix_row_in_seq
   {
    \int_compare:nTF { ##1 = 0 }
     {
      \seq_put_right:Nn \l__eagleone_sparsematrix_row_out_seq { \sparsezero }
     }
     {
      \seq_put_right:Nn \l__eagleone_sparsematrix_row_out_seq { \sparseone }
     }
   }
  \seq_use:Nn \l__eagleone_sparsematrix_row_out_seq { & } \\
 }

\ExplSyntaxOff

\begin{document}

\[
\begin{pmatrix}
0 & 1 & 0 \\
1 & 0 & 1 \\
0 & 1 & 0
\end{pmatrix}
=
\begin{sparsematrix}
0 & 1 & 0 \\
1 & 0 & 1 \\
0 & 1 & 0
\end{sparsematrix}
\]

\[
\begin{sparsematrix}
0 & 1 & 0 \\
1 & 0 & 1 \\
0 & 1 & 0
\end{sparsematrix}^2
=
\begin{sparsematrix}
1 & 0 & 1 \\
0 & 2 & 0 \\
1 & 0 & 1
\end{sparsematrix}
\]

\end{document}

enter image description here

| improve this answer | |
  • 1
    For my humble opinion: excellent. +1. – Sebastiano May 30 '19 at 20:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.