11

I would like to mark a few blocks in a matrix and I followed directions from other similar questions but I get a weird TikZ behavior .. seems that I can not have more than one marked block in a matrix? What I would like to show is the stencil of a blocked Givens rotations to annihilate non-zero elements under the diagonal starting from some column, where I update a block (red color) over the diagonal and then can work on the trailing columns or row block on the right (green color).

UPDATE: Using the answer as input I implemented my final use case.

\usepackage{pgf}
\usepackage{tikz}
\usetikzlibrary{calc,fit,matrix,arrows,automata,positioning}

\newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node (#1) {};}
\newcommand{\tikzdrawbox}[3][]{%
    \tikz[overlay,remember picture]{
    \draw[#3,#1]
      ($(left#2)+(-0.2em,0.9em)$) rectangle
      ($(right#2)+(0.2em,-0.3em)$);}
}

\newcommand\x{\times}

\begin{equation}\label{eq:blockedgivens}
\newcommand\y{\colorbox{myred}{$\times$}}
\newcommand\z{\colorbox{mygray}{$\times$}}
  \left(\begin{array}{ccccccccccccccc}
    \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x \\
     0 & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x \\
     0 &  0 & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x \\
     0 &  0 &  0 & \tikzmark{left1}\x & \x & \x & \x & \tikzmark{left3}\x & \x & \x & \x & \x & \x & \x & \x \\
     0 &  0 &  0 & \z & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x \\
     0 &  0 &  0 &  0 & \z & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x \\
     0 &  0 &  0 &  0 &  0 & \z & \x & \x & \x & \x & \x & \x & \x & \x & \x \\
     0 &  0 &  0 &  0 &  0 &  0 & \z & \tikzmark{left2} \x \tikzmark{right1} & \x & \x & \x & \tikzmark{left4} \x & \x & \x & \x \tikzmark{right3}\\
     0 &  0 &  0 &  0 &  0 &  0 &  0 & \z & \x & \x & \x & \x & \x & \x & \x \\
     0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 & \z & \x & \x & \x & \x & \x & \x \\
     0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 & \z & \x & \x & \x & \x & \x \\
     0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 & \z & \x \tikzmark{right2} & \x & \x & \x \tikzmark{right4} \\
     0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 & \z & \x & \x & \x \\
     0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 & \z & \x & \x \\
     0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 & \z & \x \\
  \end{array}\right)
  \tikzdrawbox[thick]{1}{red}
  \tikzdrawbox[thick]{2}{red}
  \tikzdrawbox[thick]{3}{green}
  \tikzdrawbox[thick]{4}{green}
\end{equation}

enter image description here

SkyWalker
  • 1,897

2 Answers2

10

Each block need its own pair of marks; I changed the definition of \tikzdrawbox; the first mandatory argument is a number used for the marks; the second optional argument allows you to pass options to \draw and the optional argument allows you to specify some "correction" to the block dimensions to prevent some borders to overlap:

\documentclass{article}
\usepackage{pgf}
\usepackage{tikz}
\usetikzlibrary{calc,fit,matrix,arrows,automata,positioning}

\newcommand\x{\times}
\newcommand\y{\colorbox{red}{$\times$}}
\newcommand\z{\colorbox{gray}{$\times$}}


\newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node (#1) {};}
\newcommand{\tikzdrawbox}[3][(0pt,0pt)]{%
    \tikz[overlay,remember picture]{
    \draw[#3]
      ($(left#2)+(-0.3em,0.9em) + #1$) rectangle
      ($(right#2)+(0.2em,-0.4em) - #1$);}
}

\begin{document}

\begin{equation}\label{eq:blockedgivens}
  \left(\begin{array}{ccccccccccccccc}
    \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x \\
     0 & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x \\
     0 &  0 & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x \\
     0 &  0 &  0 & \tikzmark{left1}\x & \x & \x & \x & \tikzmark{left3}\x & \x & \x & \x & \x & \x & \x & \x \\
     0 &  0 &  0 & \z & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x \\
     0 &  0 &  0 &  0 & \z & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x \\
     0 &  0 &  0 &  0 &  0 & \z & \x & \x & \x & \x & \x & \x & \x & \x & \x \\
     0 &  0 &  0 &  0 &  0 &  0 & \z & \tikzmark{left2} \x \tikzmark{right1} & \x & \x & \x & \tikzmark{left4} \x & \x & \x & \x \tikzmark{right3} \\
     0 &  0 &  0 &  0 &  0 &  0 &  0 & \z & \x & \x & \x & \x & \x & \x & \x \\
     0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 & \z & \x & \x & \x & \x & \x & \x \\
     0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 & \z & \x & \x & \x & \x & \x \\
     0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 & \z & \x \tikzmark{right2} & \x & \x & \x \tikzmark{right4} \\
     0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 & \z & \x & \x & \x \\
     0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 & \z & \x & \x \\
     0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 &  0 & \z & \x \\
  \end{array}\right)
  \tikzdrawbox{1}{thick,red}
  \tikzdrawbox{2}{thick,red}
  \tikzdrawbox[(-1pt,2pt)]{3}{thick,green}
  \tikzdrawbox[(-4pt,2pt)]{4}{thick,green}
\end{equation}

\end{document}

enter image description here

Gonzalo Medina
  • 505,128
  • you did it again :) – SkyWalker Sep 01 '12 at 21:26
  • if I change the style of some elements the marked blocks shift right ... any ideas why? e.g. change the zero below the top left x to \z and you will see it shifts right. – SkyWalker Sep 01 '12 at 21:49
  • I am sorry :( I have to unanswer it because doesn't work to implement my final use-case above. I get all block boundaries broken when I add all the elements I need, otherwise I have to create a new Question for the same thing and it is embarrassing :D – SkyWalker Sep 01 '12 at 22:14
  • @GiovanniAzua What is the desired output you expect to achieve? I don't understand what do you mean with "broken boundaries". – Gonzalo Medina Sep 01 '12 at 22:20
  • I updated the question, take a look, I am thinking whether to use paint to show the layout of the block marks ... e.g. the top red block is off to the right by some margin, the second red block is off by one element. They also overlap with the green blocks and they should not. The second green block is completely off to the left. – SkyWalker Sep 01 '12 at 22:22
  • @GiovanniAzua I've updated my answer; is something like that what you need? – Gonzalo Medina Sep 01 '12 at 22:32
  • yes! very close :) the red block should not overlap horizontally with the green ones ... the red blocks have a marker for 4 columns and they occupy 5 columns ... why is that??? – SkyWalker Sep 01 '12 at 22:36
  • 1
    @GiovanniAzua because you placed the marks to span five columns; take block 1, for example: initial mark is on column 4 and final mark is on column 8, so the block will span columns 4,5,6,7 and 8. – Gonzalo Medina Sep 01 '12 at 22:40
  • you are right! sorry I was off by one in the stencil :) – SkyWalker Sep 01 '12 at 23:11
  • @GiovanniAzua No problem ;-) Perhaps you could edit your question to remove the part that says that block boundaries are shifted? (It could be misleading). – Gonzalo Medina Sep 01 '12 at 23:20
9

If you don't have too many special entries(for which you can include more if cases), you can shorten the code a bit.

\documentclass{article}
\usepackage{tikz}

\begin{document}
\begin{equation}\label{eq:blockedgivens}
\left( 
\begin{tikzpicture}[baseline=(current bounding box.center)] 
\begin{scope}[xscale=0.6,yscale=0.4]
\foreach \x in {1,...,14}
    \foreach \y in {1,...,14}
    {
    \ifnum\x<\y
    \node (my-\y-\x) at (\x,-\y) {$0$};
    \else
    \node (my-\y-\x) at (\x,-\y) {$\times$};
    \fi
    }
\end{scope}
\draw[red] (my-4-4.north west) rectangle (my-8-8.south east);
\draw[red] (my-8-8.north west) rectangle (my-12-12.south east);
\end{tikzpicture}
\right)
\end{equation}
\end{document}

enter image description here

percusse
  • 157,807
  • the thing is that the matrix array I understand well, but this for scripting of TikZ is still a big mystery for me. I have tried implementing several use-cases with it and always end up bumping to strange errors or dead ended by its incomprehensible markup. – SkyWalker Sep 01 '12 at 21:58
  • 1
    @GiovanniAzua Maybe if you can provide some small examples that would illustrate those cases we can have a look together. I didn't do much scripting I just put a node at each integer grid point and if the index is bigger than the other, I change its text (which is the standard if then else clause). And to reduce the size I've used a local scaling only valid inside the scope. – percusse Sep 01 '12 at 22:01
  • Thank you percusse, where can I show you? hmm I will probably prepare a separate question otherwise this will become too OT w.r.t the OP – SkyWalker Sep 01 '12 at 22:03
  • @GiovanniAzua Indeed, a new question (or more depending on the context) would also attract more wizards :) – percusse Sep 01 '12 at 22:04