3

I need to draw a matrix of 25x25 as the one showed below: enter image description here

Since I'll need to add colors and arrows (it is an schematic diagram), I've decided to use Tikz package to draw it. I've tried in many ways, but the better approach I've found is:

\documentclass[10pt, a4paper]{article}
\usepackage{tikz}
\begin{document}

\begin{figure}
    \begin{center}
        \begin{tikzpicture}
        \draw (0,0) -- (0, 15);
        \draw (0,0) -- (15, 0);
        \draw (15,0) -- (15, 15);
        \draw (0,15) -- (15, 15);
        
        \foreach \i in {14.4, 13.8, 13.2, 12.6, 12, ..., 0.0}
            \ifnum \i<>11.4  {\node at (-\i + 15, 0.6) {0};} \else {\node at (-\i + 15, 0.6) {-1};}\fi;
        \end{tikzpicture}

        \caption{} \label{}
    \end{center}
\end{figure}

\end{document}

which outputs the following matrix:

enter image description here

As you may grasp, my intention was to recreate the matrix row per row, from the lower to the upper part of the canvas, filling each place with its respective number. It is obvious that, in order to do so, is necessary to check the position of \i in order to place a 0, a 4 or a -1. For example, in the first row, I would need to place a -1 when \i = 13.8 and \i = 11.4. The problem is that I don't know how to properly use the if sentences, it would be convenient to use nested ifs or several conditions but I could not code that part, all I have is what I post here. Any approach to generate the matrix will be appreciated.

Note: The box has dimensions of 15 per 15 and each node is separated by the distance 0.6, that guarantee that will fit 25x25 elements.

4
  • \ifnum only accepts integers. In your case, it's more like \ifdim \i pt = 11.4 pt ... \else ... \fi.
    – Symbol 1
    Jul 8, 2021 at 0:40
  • Done... Now, replacing that in my code like \ifdim \i<>11.4pt {\node at (-\i + 15, 0.6) {0};} \else {\node at (-\i + 15, 0.6) {-1};}\fi; I get the following error: Illegal unit of measure (pt inserted). Missing number, treated as zero. Jul 8, 2021 at 0:44
  • I get a first row filled with -1s btw Jul 8, 2021 at 0:45
  • \i pt, because \i is unitless.
    – Symbol 1
    Jul 8, 2021 at 0:45

2 Answers 2

8

This could be a starting point

\documentclass[border=9,tikz]{standalone}
\begin{document}

\pgfkeys{
    /big toeplitz/-2/.code={a},
    /big toeplitz/-1/.code={b},
    /big toeplitz/0/.code={c},
    /big toeplitz/1/.code={d},
    /big toeplitz/2/.code={e},
    /big toeplitz/.unknown/.code={0}
}
\tikz{
    \draw[scale=.5]
        foreach \x in {1,...,15}{
            foreach \y in {1,...,15}{
                (\x,\y)node{
                    \pgfmathtruncatemacro\difxy{\x - \y}
                    \pgfkeys{/big toeplitz/\difxy}
                }
            }
        }
    ;
}

\end{document}
5
  • Thanks! I cannot find a way to invert the diagonal as in the sample image in my post, how could I do so? Jul 8, 2021 at 1:12
  • You may replace (\x,\y) by (\x,-\y).
    – Symbol 1
    Jul 8, 2021 at 1:13
  • That works. I was trying to make the foreach loop iterate downwards inverting the sequence of numbers from {1,...,25} to {25,...,1} but I guess that doesn't work, am I right? Jul 8, 2021 at 1:15
  • 1
    Inverting the foreach is like changing the order you draw things. The end image is still that. But you came close to an alternative solution: replace \pgfmathtruncatemacro\difxy{\x - \y} with \pgfmathtruncatemacro\difxy{25 - \x - \y}.
    – Symbol 1
    Jul 8, 2021 at 1:17
  • @MiqueasEzequiel use abs(\x-\y) like this \documentclass[border=9,tikz]{standalone} \begin{document} \pgfkeys{ /big toeplitz/0/.code={4}, /big toeplitz/1/.code={-1}, /big toeplitz/5/.code={-1}, /big toeplitz/.unknown/.code={0} } \tikz{\draw[scale=.5] foreach \x in {1,...,10}{ foreach \y in {1,...,10}{ (\x,-\y) node[red]{ \pgfmathtruncatemacro\difxy{abs(\x - \y)} \pgfkeys{/big toeplitz/\difxy} }}};} \end{document}
    – Black Mild
    Jul 8, 2021 at 9:33
3

I see a neat solution by @Symbol 1 using TikZ's \pgfkeys. If one is willing to use Asymptote, then I suppose the following solution is simplest, and easier to fine-turning like adding colors, scaling, .... One can embbed into LaTeX as usual. Moreover, there are several advantages: simple code, fixed size.

enter image description here

// http://asymptote.ualberta.ca/
size(10cm);
int n=25;

for (int i=1; i<n+1; ++i)
for (int j=1; j<n+1; ++j)
if (i==j) label(scale(.8)*"4",(i,-j),red);
else if (abs(i-j)==1) label(scale(.8)*"-1",(i,-j),blue);
else if (abs(i-j)==5) label(scale(.8)*"-1",(i,-j),orange);
else label(scale(.8)*"0",(i,-j));

real a=.5;
draw((1-a,-1+a)--(1-a,-n-a)^^(n+a,-1+a)--(n+a,-n-a),linewidth(1pt));
shipout(bbox(5mm,invisible)); 

Update As OP's request, there are some 0s in the superdiagonal and the subdiagonal.

enter image description here

size(10cm);
int n=15;

for (int i=1; i<n+1; ++i)
for (int j=1; j<n+1; ++j)
if (i==j) label("$4$",(i,-j),red);
else if ((i-j==1) & (j%5 != 0) ) label("$-1$",(i,-j),blue);
else if ((i-j==-1) & (i%5 != 0)) label("$-1$",(i,-j),blue);
else if (abs(i-j)==5) label("$-1$",(i,-j),purple);
else label("$0$",(i,-j));
5
  • PS: I feel uncomfortable with TeX programming, as in this code that I have tried so far, and get stuck to go further \documentclass[border=5mm,tikz]{standalone} \begin{document} \begin{tikzpicture} \foreach \i in {1,...,10} \foreach \j in {1,...,10}{ \ifnum \i=\j \path (\i,-\j) node[red]{4}; \fi } \end{tikzpicture} \end{document}
    – Black Mild
    Jul 8, 2021 at 8:03
  • Hi Black Mild. I find your solution super cool, appreciate it. As you can notice, the original matrix has zeros in the blue diagonal (take a look to the matrix image in my post), how would you place those zeros? I could not find a way to do so. Jul 8, 2021 at 18:12
  • @MiqueasEzequiel please see my update
    – Black Mild
    Jul 9, 2021 at 3:06
  • Appreciate it man! Thanks a lot! Jul 9, 2021 at 14:18
  • @MiqueasEzequiel you are welcome!
    – Black Mild
    Jul 9, 2021 at 14:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .