4

I want to generate the following figure in LaTeX.

I know TikZ a little, so I need ideas to reproduce the same.

wanted

  • 5
    Hi. Can you add an MWE of what you have done, so that we can work from there. – shahrina ismail Dec 21 '16 at 5:17
  • 1
    If you don't know how to create a minimal working example (MWE), see this link. – CarLaTeX Dec 21 '16 at 7:36
  • Why not use Inkscape? Construct the graph and export in .tex. See at the link tex.stackexchange.com/questions/61274/…. It is very easy. Or you can use IPE. – Sebastiano Dec 21 '16 at 8:48
  • I did this using latex tables, but the code is to messy to make changes, Moreover the width of empty cells is varying after compilation, although I am fixing it. I am wondering if this can be done using Tikz in an easy way. – Astro Dec 21 '16 at 9:59
  • 1
    @VinayakAbrol Could you please change the question title to make it informative for future readers in view of the answers? – Diaa Dec 24 '16 at 8:53
14

You can start with some matrix of nodes:

\documentclass[tikz,border=2mm]{standalone} 
\usetikzlibrary{positioning, matrix}

\begin{document}
\begin{tikzpicture}[nz/.style={fill=red!80!black}]

\matrix (data) [matrix of nodes, 
nodes={draw, anchor=center, inner sep=1pt, 
        minimum height=2cm, minimum width=6mm},
        column sep=-\pgflinewidth, row sep=-\pgflinewidth]
{
$y_1$ & $y_2$ & $y_3$ & $\dots$ & $y_n$ \\
};

\matrix (Coef) [right=of data, matrix of nodes, 
     nodes in empty cells, nodes={draw, anchor=center, inner sep=1pt, 
                 minimum size=6mm},
     column sep=-\pgflinewidth, row sep=-\pgflinewidth]
{
|[nz]| & & & & $a_{1n}$ \\
& & & |[nz]| & \\
};

\draw[shorten >=1mm, shorten <=1mm] (Coef-1-1.north west)--++(90:4mm) -| (Coef-1-5.north east) node [fill=white, pos=.25] {A};

\end{tikzpicture}
\end{document}

enter image description here

Update:

I don't know if OP had enough time to learn a little bit of TiKZ, but it's Christmas and I've had some time to procrastinate ;-)

\documentclass[tikz,border=2mm]{standalone} 
\usetikzlibrary{positioning, matrix, arrows.meta}

\begin{document}
\begin{tikzpicture}[
    zero/.style={draw, minimum size=6mm, 
        inner sep=1pt, anchor=center},
    nz/.style={fill=red!80!black},
    data/.style={draw, minimum width=6mm,
        minimum height=2cm, inner sep=1pt,
        anchor=center}, 
    mymatrix/.style={matrix of math nodes,
        column sep=-\pgflinewidth,
        row sep=-\pgflinewidth,
        inner sep=0pt},
    vector/.style={mymatrix, nodes=data},
    coeff/.style={mymatrix, nodes=zero, nodes in empty cells},
    font=\sffamily,
    >=Latex
    ]

\matrix (data) [vector,
    label={[name=Y, label=data]Y},
    label={[name=m]left:m},
    label={[name=n, label=below:samples]below:n},
    ]
{
y_1 & y_2 & y_3 & \dots & y_n \\
};
\draw[shorten <=1mm] (data.north west) |- (Y);
\draw[shorten <=1mm] (data.north east) |- (Y);
\draw[->] (n)--(n-|data.east);
\draw[->] (n)--(n-|data.west);
\draw[->] (m)--(m|-data.north);
\draw[->] (m)--(m|-data.south);

\matrix (dict) [vector,
    right=8mm of data,
    label={[name=D, label=dictionary]D},
    label={[name=p, label=below:factors (atoms)]below:p},
    ]
{
d_1 & d_2 & d_3 & d_4 & d_5 & \dots & d_p \\
};
\draw[shorten <=1mm] (dict.north west) |- (D);
\draw[shorten <=1mm] (dict.north east) |- (D);
\draw[->] (p)--(p-|dict.east);
\draw[->] (p)--(p-|dict.west);

\matrix (Coef) [coeff,
    above right= 0 and 8mm of dict.south east,
    label={[name=A]A},
    label={[name=p1]right:p},
    label={[name=n, label=below:coefficients]below:n},
    ]
{
|[nz]| & & & & a_{1n} \\
& & & |[nz]| & \\
& |[nz]| & & & \\
& |[nz]| & & & |[nz]| \\
|[nz]| & & & & |[nz]| \\
& & |[nz]| & |[nz]| & \\
a_{p1} & & |[nz]| & & a_{pn}\\
};
\draw[shorten <=1mm] (Coef.north west) |- (A);
\draw[shorten <=1mm] (Coef.north east) |- (A);
\draw[->] (p1)--(p1|-Coef.north);
\draw[->] (p1)--(p1|-Coef.south);
\draw[->] (n)--(n-|Coef.east);
\draw[->] (n)--(n-|Coef.west);

\path (data.east)-- node {$=$} (dict.west);
\path (dict.east)-- node {$\times$} (dict-|Coef.west);

\node[zero, above left=8mm and 0 of data.north east, label=right:zero] (z1) {};
\node[zero, nz, above=-\pgflinewidth of z1.north, label=right:nonzero] (nz1) {};
\end{tikzpicture}
\end{document}

enter image description here

9

A PSTricks solution:

\documentclass{article}

\usepackage{geometry} % to avoid `overfull \hbox' warning
\usepackage{xfp}
\usepackage{pstricks-add}
\psset{dimen = m}

% simplifies code
\def\vect#1{\mathbf{#1}}

\def\block#1[#2]#3#4#5{%
  \multido{\r = \fpeval{0.4+0.7*(#1-1)+(#2)*\width}+\width}{#3}{%
    \psframe(\r,0.75)(\fpeval{\r+\width},\fpeval{0.75+\height*\width})}
  \multido{\r = \fpeval{0.4+0.7*(#1-1)+(#2+0.5)*\width}+\width, \i = 1+1}{%
    \fpeval{#3-2}}{%
      \rput(\r,\fpeval{0.75+0.5*\height*\width}){$\vect{#4}_{\i}$}}
    \rput(\fpeval{0.4+0.7*(#1-1)+(#2+#3-1.5)*\width},
          \fpeval{0.75+0.5*\height*\width}){$\dots$}
    \rput(\fpeval{0.4+0.7*(#1-1)+(#2+#3-0.5)*\width},
          \fpeval{0.75+0.5*\height*\width}){$\vect{#4}_{#5}$}}

\def\labelH#1[#2](#3)#4#5{%
  \pcline{<->}(\fpeval{0.4+0.7*(#1-1)+(#2)   *\width},0.5)%
              (\fpeval{0.4+0.7*(#1-1)+(#2+#3)*\width},0.5)
  \ncput*{$\mathsf{#4}$}
  \rput(\fpeval{0.4+0.7*(#1-1)+(#2+0.5*#3)*\width},0.15){\textsf{#5}}}

\def\labelV#1[#2](#3)(#4)#5{%
  \pcline{<->}(\fpeval{(#1)*0.27+0.4+0.7*(#2-1)+(#3)*\width},0.75)%
              (\fpeval{(#1)*0.27+0.4+0.7*(#2-1)+(#3)*\width},\fpeval{0.75+(#4)*\width})
  \ncput*{$\mathsf{#5}$}}

\def\span#1[#2](#3)#4#5#6#7#8{%
  \pnode(\fpeval{0.4+(#1-1)*0.7+(#2)   *\width},\fpeval{0.75+(#4)*\width}){#5}
  \pnode(\fpeval{0.4+(#1-1)*0.7+(#2+#3)*\width},\fpeval{0.75+(#4)*\width}){#6}
  \ncbar[angle = 90]{#5}{#6}
  \ncput*{$\mathsf{#7}$}
  \rput(\fpeval{0.4+(#1-1)*0.7+(#2+0.5*#3)*\width},\fpeval{1.5+(#4)*\width})%
       {\textsf{#8}}}

\def\coeff(#1,#2)[#3]{%
  \psframe[
    fillstyle = solid,
    fillcolor = #3
  ](\fpeval{#1-\width},\fpeval{#2-\width})(#1,#2)}

\def\nonzero#1#2{%
  \coeff(\fpeval{1.8+(#1+\blocksA+\blocksB)*\width},
         \fpeval{0.75+(#2)*\width})[Red]}

\def\note(#1,#2)#3{%
  \rput(\fpeval{1.8+(#1+\blocksA+\blocksB-0.5)*\width},
        \fpeval{0.75+(#2-0.5)*\width}){$a_{#3}$}}

\def\expla(#1)[#2]#3{%
  \coeff(\fpeval{0.4+(\blocksA+0.5)*\width},
         \fpeval{max(0.5+(\height+2.5)*\width,2.25+(#1)*\width)})[#2]
  \rput[l](\fpeval{0.6+(\blocksA+0.5)*\width},
           \fpeval{max(0.5+(\height+2.5)*\width,2.25+(#1)*\width)-0.5*\width})%
          {\textsf{#3}}}

% color
\definecolor{Red}{rgb}{0.647,0.129,0.149}

% parameters
\def\width{0.6}
\def\height{4}
\def\blocksA{5}
\def\blocksB{7}


\begin{document}

\begin{center}
\begin{pspicture}(\fpeval{2.15+(2*\blocksA+\blocksB)*\width},
                  \fpeval{max(2.25+(\height+1)*\width,1.2+\blocksB*\width)})
  \block{1}[0]{\blocksA}{y}{n}
  \labelV{-1}[1](0)(\height){m}
  \labelH{1}[0](\blocksA){n}{samples}
  \span{1}[0](\blocksA){\height}{A}{B}{Y}{data}
  \rput(\fpeval{0.75+\blocksA*\width},\fpeval{0.75+0.5*\height*\width}){$\mathbf{=}$}
  \block{2}[\blocksA]{\blocksB}{d}{p}
  \labelH{2}[\blocksA](\blocksB){p}{factors (atoms)}
  \span{2}[\blocksA](\blocksB){\height}{C}{D}{D}{directory}
  \rput(\fpeval{1.45+(\blocksA+\blocksB)*\width},
        \fpeval{0.75+0.5*\height*\width}){$\times$}
  \multido{\rA = \fpeval{1.8+(\blocksA+\blocksB+1)*\width}+\width}{\blocksA}{%
    \multido{\rB = \fpeval{0.75+\width}+\width}{\blocksB}{%
      \coeff(\rA,\rB)[white]}}
  \nonzero{3}{1}
  \nonzero{3}{2}
  \nonzero{4}{2}
  \nonzero{1}{3}
  \nonzero{5}{3}
  \nonzero{2}{4}
  \nonzero{5}{4}
  \nonzero{2}{5}
  \nonzero{4}{6}
  \nonzero{1}{7}
  \note(1,1){p1}
  \note(\blocksA,1){pn}
  \note(\blocksA,\blocksB){1n}
  \labelH{3}[\blocksA+\blocksB](\blocksA){n}{coefficients}
  \labelV{1}[3](2*\blocksA+\blocksB)(\blocksB){p}
  \span{3}[\blocksA+\blocksB](\blocksA){\blocksB}{E}{F}{A}{}
  \expla(\height)[white]{zero}
  \expla(\height+1)[Red]{nonzero}
\end{pspicture}
\end{center}

\end{document}

output

All you have to do is change the values of the parameters, and the drawing will be adjusted accordingly.

  • Nice @Svend ! Right now its a bit complicated, but I will consider this in future. – Astro Dec 22 '16 at 6:00
  • Tveskæg my best compliments for the job. You are very good. – Sebastiano Dec 23 '16 at 23:01
  • I know pstricks but I not understand because just about only TikZ. I have upvoted, immediately. Was 5 and now 6. Merry Christmas for you and your family. – Sebastiano Dec 23 '16 at 23:22
8

Not adding much to the previous answers, except a different way of drawing the cells in the grid.

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{chains,arrows.meta}
\tikzset{%
cell/.style={
  minimum height=8em, minimum width=2em,
  inner sep=0pt,      outer sep=0pt,
  draw,thick
},
every block/.style={
  inner sep=0, minimum size=2em, text depth=0
},
block 0/.style={every block/.try},
block 1/.style={every block/.try, fill=red!50!black,
},
grid lines/.style={draw=black, thick},
offset to/.style args={#1 and #2}{to path={
  ([shift={(#1,#2)}]\tikztostart) -- ([shift={(#1,#2)}]\tikztotarget)
  \tikztonodes}}, 
offset y/.style={offset to=0 and #1}, offset x/.style={offset to=#1 and 0}
}
\begin{document}
\begin{tikzpicture}[start chain=going {at=(\tikzchainprevious.south east)},
  anchor=south west,align=center, line cap=round, line join=round,
  >=Triangle, every node/.style={align=center}, x=2em, y=2em]
\begin{scope}[local bounding box=data]
\foreach \y in {1,2,3,-,n}
  \node [on chain, cell] (y-\y) {$\expandafter\if\y-\ldots\else y_{\y}\fi$};
\end{scope}
\node [on chain, cell, draw=none] (equals) {$=$};
\begin{scope}[local bounding box=dictionary]
\foreach \d in {1,2,3,4,5,-,p}
  \node [on chain, cell] (d-\d) {$\expandafter\if\d-\ldots\else d_{\d}\fi$};
\end{scope}
\node [on chain, cell, draw=none] (times) {$\times$};
\coordinate [on chain] (grid origin);
\begin{scope}[shift=(grid origin),  local bounding box=grid]
\foreach \k [count=\y from 0] in {4,6,17,9,8,2,16}
   \foreach \x [evaluate={\c=int(mod(int(\k / (2^\x)), 2));}] in {0,...,4}
     \node [block \c/.try] (a-\y-\x) at (4-\x, \y) {};
\draw [grid lines/.try, step=2em] grid ++(5,7);
\node [every block] at (4,6) {$a_{1n}$};
\node [every block] at (0,0) {$a_{p1}$};
\node [every block] at (4,0) {$a_{pn}$};
\end{scope}

\draw [{Bar[left]}-{Bar[right]}] (data.north west) to [offset y=1/4]
  node [midway, above] {Data \\ $Y$} (data.north east);
\draw [<->] (data.south east) to [offset y=-1/4] 
  node [midway, below] {$n$ \\ samples} (data.south west);
\draw [<->] (data.south west) to [offset x=-1/4] 
  node [midway, left] {$m$}  (data.north west);

\draw [{Bar[left]}-{Bar[right]}] (dictionary.north west) to [offset y=1/4]
  node [midway, above] {Dictionary \\ $D$} (dictionary.north east);
\draw [<->] (dictionary.south west) to [offset y=-1/4]
  node [midway, below] {$p$ \\ factors (atoms)} (dictionary.south east);

\draw [{Bar[left]}-{Bar[right]}] (grid.north west) to [offset y=1/4]
  node [midway, above] {$A$} (grid.north east);
\draw [Triangle-Triangle] (grid.south west) to [offset y=-1/4] 
  node [midway, below] {$n$ \\ coefficients} (grid.south east);
\draw [<->] (grid.south east) to [offset x=1/4] 
  node [midway, right] {$p$} (grid.north east);

\node [block 1, grid lines, label=0:non-zero] at ([shift={(0,5)}]y-n) {};
\node [block 0, grid lines, label=0:zero]     at ([shift={(0,4)}]y-n){};
\end{tikzpicture}
\end{document}

enter image description here

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.