# Does Anyone Know How to Two Draw MIMO Blocks Connected Together?

Does Anyone Know How to Two Draw MIMO Blocks Connected Together? I am doing a project and need to draw a schematic that looks similar to the one below by using LATEX. Does anyone know how to do that? In particular, I want to know how to put texts inside the block. I also want to know how to create these two blocks as well as how to connect them PROPERLY. The following is what I currently have.

\documentclass{article}
\usepackage{amsfonts}
\usepackage{siunitx}
\usepackage[table]{xcolor}
\usepackage{booktabs}
\usepackage[margin=0.5in]{geometry}
\usepackage{tikz}
\usetikzlibrary{arrows, automata, backgrounds, fit, matrix, arrows.meta, calc, positioning}
\begin{document}
\begin{tikzpicture}[>=stealth]
\matrix[matrix of math nodes, nodes in empty cells, draw] (blockA) at (0,2)
{
A & & & F \\
B & & & G \\
C & & & H \\
D & & & I  \\
& & & & E \\
};
\matrix[matrix of math nodes,nodes in empty cells,draw,minimum width=30pt,below=of blockA] (blockB)
{
A & & & F \\
B & & & G \\
C & & & H \\
D & & & I \\
E & & & J \\
};
\node at (blockB) {$Block B$};

\foreach \i in {1,2,3,4,5}
{
\draw[->] let \p1 = (blockA.west), \p2 = (blockA-\i-\i.west), \p3 = (blockB.west), \p4 = (blockB-\i-1.west) in (\x3,\y4) -|
++(-2.4+0.2*\i,1) |- (\x1,\y2);
\draw[->] let \p1 = (blockA.east), \p2 = (blockA-\i-\i.east), \p3 = (blockB.east), \p4 = (blockB-\i-1.east) in (\x1,\y2) -|
++(1.6-0.2*\i,-1) |- (\x3,\y4);
}
\end{tikzpicture}
\end{document}


To make it symmetrical, I used absolute coordinates for the midpoint. The only tricky bit is finding a y value below the top block and above the bottom block.

Since there were a odd number of rows, I simply added the text as part of the matrix. If there were an even number, one could reserve the space using \hphantom{\text{Block A}} and overwrite the node as before.

\documentclass{article}
\usepackage{amsfonts}
\usepackage{siunitx}
\usepackage[table]{xcolor}
\usepackage{booktabs}
\usepackage[margin=0.5in]{geometry}
\usepackage{tikz}
\usetikzlibrary{arrows, automata, backgrounds, fit, matrix, arrows.meta, calc, positioning}
\begin{document}
\begin{tikzpicture}[>=stealth]
\matrix[matrix of math nodes, nodes in empty cells, draw] (blockA) at (0,2)
{
A & & F \\
B & & G \\
C & \text{Block A} & H \\
D & & I \\
E & & J \\
};
\matrix[matrix of math nodes,nodes in empty cells,draw,below=of blockA] (blockB)
{
A & & F \\
B & & G \\
C & \text{Block B} & H \\
D & & I \\
E & & J \\
};

\foreach \i in {1,2,3,4,5}
{
\draw[->] let \p1 = (blockA.west), \p2 = (blockA-\i-1.west), \p3 = (blockB.west), \p4 = (blockB-\i-1.west) in (\x3,\y4) -|
(-4+0.2*\i,0) |- (\x1,\y2);
\draw[->] let \p1 = (blockA.east), \p2 = (blockA-\i-1.east), \p3 = (blockB.east), \p4 = (blockB-\i-1.east) in (\x1,\y2) -|
(4-0.2*\i,0) |- (\x3,\y4);
}
\end{tikzpicture}
\end{document}


• Thank you so much. It works. Could you elaborate on what I should do if the number of rows is an even number. I don't really understand the sentence "If there were an even number, one could reserve the space using \hphantom{\text{Block A}} and overwrite the node as before." – LARRrrrY65464 Jul 9 '18 at 1:39
• Never mind. I figured out what you mean. I wonder what if the number of arrows on the left is 4 for both blocks (i.e., the number of rows is also 4, that is, from A to D), and the number of arrows on the right side remains unchanged for both blocks. Could you show me the code for that if it is not too much trouble? – LARRrrrY65464 Jul 9 '18 at 1:58
• The lines are generated using the foreach loop (which I personally regard as an unnecessary complication). The x values come from the edges of the block, but the y values come from the matrix entries (which are automatically assigned names like BlockA-1-1). – John Kormylo Jul 9 '18 at 13:58

Here is a solution that defines a new shape named block that can be used with an arbitrary number of in- and outputs. I made this once for a similar problem. Pros:

• Arbitrary number of in- and outputs
• Configurable space between in-/outputs
• Tikz anchors at in-/outputs
• Shape is the same as the default rectangle shape
• flip option to have inputs on the right and outputs on the left

If you want, I could elaborate on the code, but you can also use it out of the box.

\documentclass[tikz]{standalone}

\usetikzlibrary{positioning}

\makeatletter
\newdimen\block@iospacing
\newdimen\block@height

\newif\if@block@flip

\tikzset{
block/.code={
\pgfkeys{
/block/.cd,
#1
}
\pgfmathsetlengthmacro{\block@height}{%
max(10mm, int(max(\block@inputs,\block@outputs) * \block@iospacing))}
\tikzset{
draw,
align=center,
minimum width = 15mm,
minimum height = \block@height,
shape=block
}
}
}
\pgfkeys{
/block/.is family,
/block/.cd,
inputs/.code={
\pgfmathparse{int(#1)}
\let\block@inputs=\pgfmathresult
},
inputs=1,
outputs/.code={
\pgfmathparse{int(#1)}
\let\block@outputs=\pgfmathresult
},
outputs=1,
io spacing/.code=\setlength\block@iospacing{#1},
io spacing=5mm,
flip/.is choice,
flip/true/.code={\@block@fliptrue\def\@block@flipbool{1}},
flip/false/.code={\@block@flipfalse\def\@block@flipbool{0}},
flip/.default=true,
flip=false,
}

\pgfdeclareshape{block}{
\inheritsavedanchors[from={rectangle}]
\savedanchor\centerpoint{%
\pgf@x=.5\wd\pgfnodeparttextbox%
\pgf@y=.5\ht\pgfnodeparttextbox%
}
\inheritsavedanchors[from=rectangle]
\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{north}
\inheritanchor[from=rectangle]{north west}
\inheritanchor[from=rectangle]{north east}
\inheritanchor[from=rectangle]{center}
\inheritanchor[from=rectangle]{text}
\inheritanchor[from=rectangle]{west}
\inheritanchor[from=rectangle]{east}
\inheritanchor[from=rectangle]{mid}
\inheritanchor[from=rectangle]{mid west}
\inheritanchor[from=rectangle]{mid east}
\inheritanchor[from=rectangle]{base}
\inheritanchor[from=rectangle]{base west}
\inheritanchor[from=rectangle]{base east}
\inheritanchor[from=rectangle]{south}
\inheritanchor[from=rectangle]{south west}
\inheritanchor[from=rectangle]{south east}
\savedmacro\blockinputs{%
\pgfmathparse{int(\block@inputs)}%
\let\blockinputs=\pgfmathresult}%
\savedmacro\blockoutputs{%
\pgfmathparse{int(\block@outputs)}%
\let\blockoutputs=\pgfmathresult}%
\savedmacro\blockmaxio{%
\pgfmathparse{int(max(\block@inputs,\block@outputs))}%
\let\blockmaxio=\pgfmathresult}%
\savedmacro\blockflip{%
\pgfmathparse{\@block@flipbool}%
\let\blockflip=\pgfmathresult}%
\saveddimen\halfwidth{\pgfmathsetlength\pgf@x{%
\pgfkeysvalueof{/pgf/minimum width}/2}\pgfmathresult}
\saveddimen\halfheight{\pgfmathsetlength\pgf@x{%
\pgfkeysvalueof{/pgf/minimum height}/2}\pgfmathresult}
\saveddimen\iospacing{\pgfmathsetlength\pgf@x{%
\block@iospacing}\pgfmathresult}
\inheritbackgroundpath[from={rectangle}]
\pgfmathloop%
\ifnum\pgfmathcounter>\blockinputs\relax%
\else%
\pgfutil@ifundefined{pgf@anchor@block@input \pgfmathcounter}{%
\expandafter\xdef\csname pgf@anchor@block@input %
\pgfmathcounter\endcsname{\noexpand%
\pgf@sh@lib@block@in@anchor{\pgfmathcounter}%
}%
}{}
\repeatpgfmathloop%
\pgfmathloop%
\ifnum\pgfmathcounter>\blockoutputs\relax%
\else%
\pgfutil@ifundefined{pgf@anchor@block@output \pgfmathcounter}{%
\expandafter\xdef\csname pgf@anchor@block@output %
\pgfmathcounter\endcsname{\noexpand%
\pgf@sh@lib@block@out@anchor{\pgfmathcounter}%
}%
}{}
\repeatpgfmathloop%
}%
}

\def\pgf@sh@lib@block@in@anchor#1{%
\pgf@process{\centerpoint}%
\pgf@ya=\pgf@y%
\ifnum\blockflip=0\relax%
\pgf@process{\southwest}%
\else%
\pgf@process{\northeast}%
\fi%
\pgfmathsetlength\pgf@y{\pgf@ya + (0.5*(\blockinputs+1)-#1)*\iospacing}
}
\def\pgf@sh@lib@block@out@anchor#1{%
\pgf@process{\centerpoint}%
\pgf@ya=\pgf@y%
\ifnum\blockflip=0\relax%
\pgf@process{\northeast}%
\else%
\pgf@process{\southwest}%
\fi%
\pgfmathsetlength\pgf@y{\pgf@ya + (0.5*(\blockoutputs+1)-#1)*\iospacing}
}
\makeatother

\begin{document}
\begin{tikzpicture}[block/.append style={minimum width=3cm},iolabel/.style={text width=2.5mm,align=center}]
\node[block={inputs=4,outputs=5}](blockA){Block A};
\node[block={inputs=5,outputs=4,flip,io spacing=8mm},below=of blockA](blockB){Block B};

\foreach[count = \i] \letter in {F,...,J}{
\node[left,iolabel] at (blockA.output \i) {\letter};
\node[left,iolabel] at (blockB.input \i) {\letter};
\draw[->] (blockA.output \i) -- ++(2-\i*0.2,0) |- (blockB.input \i);
}
\foreach[count = \i] \letter in {A,...,D}{
\node[right,iolabel] at (blockA.input \i) {\letter};
\node[right,iolabel] at (blockB.output \i) {\letter};
\draw[->] (blockB.output \i) -- ++(-2+\i*0.2,0) |- (blockA.input \i);
}
\end{tikzpicture}
\end{document}


The result of this code is: