tikz add tag
Diaa
# 1. Parallel Form #
---

For the following parallel signal flow diagram, I need the edges of labels with `zero` numeric values to be not drawn robustly.

![Untitled.png](/image?hash=5171eeb84064b69ba948b274bf71d1ab48bb947d78c184f629fe0adc401a3806)

```
\def\GraphInput{-24/-3,0/-4,-24/0}

\documentclass[tikz,border=5mm]{standalone}

\usetikzlibrary{calc,decorations.markings,positioning,arrows.meta,matrix}
\makeatletter
\pgfmathdeclarefunction{Dim}{1}{%
	\begingroup%
	\pgfmath@count=0\relax
	\edef\pgfutil@tmpb{#1}%
	\pgfutil@for\pgfutil@tmpa:={\pgfutil@tmpb}\do{%
		\advance\pgfmath@count by1\relax}%
	\edef\pgfmathresult{\the\pgfmath@count}% 
	\pgfmath@smuggleone\pgfmathresult% 
	\endgroup}  
\makeatother
\begin{document}
	\begin{tikzpicture}[
		node distance = 4em and 4em, 
		font=\normalsize, % https://tex.stackexchange.com/a/160987/2288
		relative = false,
		amark/.style = {
			decoration={             
				markings,   
				mark=at position {0.5} with { 
					\arrow{stealth},
				}
			},
			postaction={decorate},
			nodes={inner xsep=0pt},
			edge label={#1}
		},
		amark'/.style = {
			decoration={             
				markings,   
				mark=at position {0.5} with { 
					\arrow{stealth},
				}
			},
			postaction={decorate},
			nodes={inner xsep=0pt},
			edge label'={#1}
		},
		terminal/.style 2 args={draw,alias=ln,circle,inner sep=2pt},
		]
		% number of insertions
		\pgfmathtruncatemacro{\mydim}{Dim("\GraphInput")}
		% local bounding box is a trick that all distances derive from node distance
		\path[local bounding box=graph] 
		foreach \X/\Y [count=\Z] in \GraphInput {
			% draw the inner nodes in a loop
			\ifnum\Z=1
			node[terminal] (sX-\Z){} node[right=of sX-\Z,terminal] (X-\Z){}
			\else
			node[terminal,below=of sX-\the\numexpr\Z-1] (sX-\Z){} 
			node[right=of sX-\Z,terminal] (X-\Z){}
			\fi
		}
		% draw R and S nodes
		node[left=6em of graph,terminal,label=left:{$R(s)$}] (R){}
		node[right=6em of graph,terminal,label=right:{$C(s)$}] (C){}
		% loop for connections
		foreach \X/\Y [count=\Z] in \GraphInput {
			% bug in pgf, out does not get parsed properly
			[/utils/exec=\pgfmathsetmacro{\myout}{90-(\Z-1)*180/(\mydim-1)}]
			(sX-\Z) edge[amark={$1/s$}] (X-\Z)
			(X-\Z) edge[amark'={$\Y$},out=-90,in=-90,looseness=1.25] (sX-\Z)
			\ifnum\Z>\numexpr\mydim/2
			(R) edge[amark'={$\X$},out=\myout,in=180] (sX-\Z)
			(X-\Z) edge[amark'={$1$},out=0,in=180-\myout] (C)
			\else
			(R) edge[amark={$\X$},out=\myout,in=180] (sX-\Z)
			(X-\Z) edge[amark={$1$},out=0,in=180-\myout] (C)
			\fi
		};
	\end{tikzpicture}
\end{document}
```
---
# 2. Phase-Variable Form #

## Synopsis of how to draw

For the following  set of state-space equations
![E89IJ.png](/image?hash=af45fe9846ba4cde355e6ef1f4c9fbbb1f117552f17893e649d2d5d5636ba7cf)

the desired output should be

![O32b3.png](/image?hash=8245f7757c7b553d0f98e98b2c894d32613863cdb71c8654497a5784701a6e44)

after following the instructions shown here ([1](https://i.ibb.co/QkHfLbH/image.png), [2](https://i.ibb.co/Cs2Qpvj/image.png), [3](https://i.ibb.co/mCLtK6V/image.png), [4](https://i.ibb.co/kgV8qSQ/image.png)) adopted from the book *Control Systems Engineering* 

### General remarks

Every row of the state equations (except the last one) represents an equation of `sXi(s)` with all edges pointing to the node of the respective `sXi(s)`

The last row represents the equation of output `Y(s)` where every edge connecting with it should have an arrow pointing towards it.

So, generally, in the drawing, the nodes of `R(s)` and `Xi(s)` are sources with arrows going out of them, while the nodes of `sXi(s)` and `Y(s)` are destinations with arrows pointing towards them.

## The question

I need to apply the same approach (of hiding the zero-labelled edges) to the following phase-variable form for this example while robustly drawing the missing branch here of label `3` from `X3` to `sX1` as indicated in the following matrix definition

![Untitled.png](/image?hash=927aa183e58970d20dafa411ff8aada17a6fadc1061fdc69e893888127a73bf0)

```
% define the  matrix 
\edef\mmat{%
	{2,-5,3,0},% <= a missing edge of label "3" should be drawn from X3 to sX1
	{0,-2,2,5},%
	{1,-3,0,7},%
	{-4,0,9,0}%
}
\documentclass[tikz,border=5mm]{standalone}
\usetikzlibrary{calc,decorations.markings,positioning,arrows.meta}
\newif\iflabrev
\begin{document}
    \begin{tikzpicture}[node distance = 15 mm,
        label revd/.is if=labrev,
        label revd/.default=true,
        amark/.style = {
            decoration={             
                markings,   
                mark=at position {0.5} with { 
                    \arrow{stealth},
                    \iflabrev \node[below] {#1};\else \node[above] {#1};\fi
                }
            },
            postaction={decorate}
        }, % make the mark an entry of the \mmat matrix
        pmark/.style n args={2}{amark={$%
            \pgfmathparse{int({\mmat}[\numexpr#1][\numexpr#2])}%
                \pgfmathresult$}},
        terminal/.style 2 args={draw,alias=ln,circle,inner sep=2pt,label={#1:#2}},
        % semicircle path
        semicircle/.style={to path={let \p1=($(\tikztotarget)-(\tikztostart)$)
            in \ifdim\x1>0pt
              (\tikztostart.north) arc[start angle=180,end angle=0,radius=0.5*\x1]
            \else
              (\tikztostart.south) arc[start angle=0,end angle=-180,radius=-0.5*\x1]
            \fi}}
        ]
        \pgfmathtruncatemacro{\dimy}{dim({\mmat})} % number of rows
        \pgfmathtruncatemacro{\dimx}{dim({\mmat}[0])} % number of columns
        % create the graph
        \path % R node
        node[terminal={left}{$R(S)$},alias={X-\dimy}] (R) {}
        % loop over matrix entries
        foreach \Y [evaluate=\Y as \X using {int(\dimy-\Y)}]
        in {1,...,\numexpr\dimy-1}
        {node[right=of ln,terminal={below right}{% sX_i node
            $sX_{\X}(s)$}](sX-\X){}
        node[right=of ln,terminal={below right}{% X_i node
            $X_{\X}(s)$}](X-\X){}
        % ege from sX_i to X_i  
        (sX-\X) edge[amark={$\frac{1}{s}$}] (X-\X)
        % edge from X_{i+1} to X_i  (R had an alias)
        (X-\the\numexpr\X+1) edge[pmark={\X-1}{\X}] (sX-\X)
        % semicircle edge from X_i to sX_i
        (X-\X) edge[semicircle,label revd,pmark={\X-1}{\X-1}] (sX-\X)
        % various semicircles
        \ifnum\Y>1
         (R) edge[semicircle,pmark={\X-1}{\dimx-1}] (sX-\X) 
         foreach \Z in {1,...,\numexpr\Y-1} {
          (X-\X) edge[semicircle,pmark={\X+\Z-1}{\X-1}] (sX-\the\numexpr\X+\Z)
         }
        \fi
        }% the Y node
        node[right=of ln,terminal={right}{$Y(s)$}](Y){}
        (X-1) edge[pmark={\dimy-1}{0}] (Y)
        % semicircles goint to Y
        foreach \Y [evaluate=\Y as \X using {int(\dimy-\Y)}]
         in {1,...,\numexpr\dimy-2}
        {(X-\X) edge[semicircle,pmark={\dimy-1}{\X-1}] (Y)};
    \end{tikzpicture}
\end{document}
```
Top Answer
marmot
This is an answer to the updated question. It has some perhaps more powerful styles, at least when dealing with integers or numbers. Instead of trying to squeeze everything in one loop, now the strategy is to draw the horizontal part first so that all nodes on the line are defined, and then deal with the off-diagonal entries. (I sort of regret that I did not away with the `label revd`, a simple edge label would probably be better and easier to `swap`.)
```
% define the  matrix 
\edef\mmat{%
	{2,-5,3,2},% <= a missing edge of label "3" should be drawn from X3 to sX1
	{-6,-2,2,5},%
	{1,-3,-4,7},%
	{-4,6,9,0}%
}
\documentclass[tikz,border=5mm]{standalone}
\usetikzlibrary{calc,decorations.markings,positioning,arrows.meta}
\newif\iflabrev
\begin{document}
    \begin{tikzpicture}[node distance = 15 mm,
        label revd/.is if=labrev,
        label revd/.default=true,
        amark/.style = {
            decoration={             
                markings,   
                mark=at position {0.5} with { 
                    \arrow{stealth},
                    \iflabrev \node[below] {#1};\else \node[above] {#1};\fi
                }
            },
            postaction={decorate}
        }, % make the mark an entry of the \mmat matrix
        pmark/.code n args={2}{%
		\pgfmathtruncatemacro{\myi}{int({\mmat}[\numexpr#1][\numexpr#2])}%
		\tikzset{suppress if 0=\myi,
			amark={$\myi$}}% <- changed
		},
        terminal/.style 2 args={draw,alias=ln,circle,inner sep=2pt,label={#1:#2}},
        % semicircle path
        semicircle/.style={to path={let \p1=($(\tikztotarget)-(\tikztostart)$)
            in \ifdim\x1>0pt
              (\tikztostart.north) arc[start angle=180,end angle=0,radius=0.5*\x1]
            \else
              (\tikztostart.south) arc[start angle=0,end angle=-180,radius=-0.5*\x1]
            \fi}},
		add key if/.code n args={3}{\pgfmathtruncatemacro{\itest}{(#1?0:1)}%
		\ifcase\itest
		 \tikzset{#2}%
		\else
		 \tikzset{#3}%
		\fi
		},suppress if 0/.style={add key if={#1==0}{opacity=0}{}},
		switch if/.style 2 args={}
        ]
        \pgfmathtruncatemacro{\dimy}{dim({\mmat})} % number of rows
        \pgfmathtruncatemacro{\dimx}{dim({\mmat}[0])} % number of columns
        % create the graph
        \path % R node
        node[terminal={left}{$R(S)$},alias={X-\dimy}] (R) {}
        % loop over matrix entries
        foreach \Y [evaluate=\Y as \X using {int(\dimy-\Y)}]
        in {1,...,\numexpr\dimy-1}
        {node[right=of ln,terminal={below right}{% sX_i node
            $sX_{\X}(s)$}](sX-\X){}
        node[right=of ln,terminal={below right}{% X_i node
            $X_{\X}(s)$}](X-\X){}
        % ege from sX_i to X_i  
        (sX-\X) edge[amark={$\frac{1}{s}$}] (X-\X)
        % edge from X_{i+1} to X_i  (R had an alias)
        (X-\the\numexpr\X+1) edge[pmark={\X-1}{\X},swap] (sX-\X)
        % semicircle edge from X_i to sX_i
        (X-\X) edge[semicircle,label revd,pmark={\X-1}{\X-1}] (sX-\X)
		}
        node[right=of ln,terminal={right}{$Y(s)$},alias=sX-\dimy](Y){}
        (X-1) edge[pmark={\dimy-1}{0}] (Y) 
		% we are now done with the horizontal part,
		% and have also dealt with the entries on the diagonal and 
		% the {i-1},i entries
		% now we deal with the matrix entries
		foreach \X in {1,...,\the\numexpr\dimx-1}
		{ foreach \Y in {\the\numexpr\X+1,...,\dimy} 
		{ 
		\unless\ifnum\X\Y=1\dimy
		  (X-\X) edge[semicircle,pmark={\Y-1}{\X-1},add key if={\Y==\dimy}{}{label revd}] (sX-\Y)
		\fi
		\unless\ifnum\numexpr\Y-\X=\numexpr1\relax
		(X-\Y) edge[semicircle,pmark={\X-1}{\Y-1}] (sX-\X)
		\fi
		}};
    \end{tikzpicture}
\end{document}
```
![Screen Shot 2020-12-20 at 12.25.17 PM.png](/image?hash=8f4d0e9312405efae69d3967c15b3ee8efc3cbb53e199c9672bc663cb5ac06dd)

**Older post**: Here is something that allows you to suppress some elements of the graph conditionally. There is a more general key,
```
suppress if equal
```
which takes two arguments (which have to be expandable), and sets the opacity to zero if these arguments expand to the same value/token. Then there is a derived style
```
supress if 0
```
that takes one argument and suppresses the edge if the argument expands to `0`. This style is really just the above key with one argument set to zero, so if you have other critical values, you can construct them analogously. (Of course you can generalize the above to change e.g. the color instead of the opacity.) Note also that if you set the opacity later to some value explicitly in that edge, `suppress if 0` has to come last.
   
```
\documentclass[tikz,border=5mm]{standalone}

\usetikzlibrary{calc,decorations.markings,positioning,arrows.meta,matrix}
\makeatletter
\pgfmathdeclarefunction{Dim}{1}{%
	\begingroup%
	\pgfmath@count=0\relax
	\edef\pgfutil@tmpb{#1}%
	\pgfutil@for\pgfutil@tmpa:={\pgfutil@tmpb}\do{%
		\advance\pgfmath@count by1\relax}%
	\edef\pgfmathresult{\the\pgfmath@count}% 
	\pgfmath@smuggleone\pgfmathresult% 
	\endgroup}  
\makeatother
\begin{document}
	\begin{tikzpicture}[
		node distance = 4em and 4em, 
		font=\normalsize, % https://tex.stackexchange.com/a/160987/2288
		relative = false,
		amark/.style = {
			decoration={             
				markings,   
				mark=at position {0.5} with { 
					\arrow{stealth},
				}
			},
			postaction={decorate},
			nodes={inner xsep=0pt},
			edge label={#1}
		},
		amark'/.style = {
			decoration={             
				markings,   
				mark=at position {0.5} with { 
					\arrow{stealth},
				}
			},
			postaction={decorate},
			nodes={inner xsep=0pt},
			edge label'={#1}
		},
		terminal/.style 2 args={draw,alias=ln,circle,inner sep=2pt},
		suppress if equal/.code 2 args={\edef\mytestA{#1}%
		\edef\mytestB{#2}%
		\ifx\mytestA\mytestB\relax
		\tikzset{opacity=0}
		\fi
		},suppress if 0/.style={suppress if equal={0}{#1}}
		]
		\def\GraphInput{-24/-3,0/-4,-24/0}
		% number of insertions
		\pgfmathtruncatemacro{\mydim}{Dim("\GraphInput")}
		% local bounding box is a trick that all distances derive from node distance
		\path[local bounding box=graph] 
		foreach \X/\Y [count=\Z] in \GraphInput {
			% draw the inner nodes in a loop
			\ifnum\Z=1
			node[terminal] (sX-\Z){} node[right=of sX-\Z,terminal] (X-\Z){}
			\else
			node[terminal,below=of sX-\the\numexpr\Z-1] (sX-\Z){} 
			node[right=of sX-\Z,terminal] (X-\Z){}
			\fi
		}
		% draw R and S nodes
		node[left=6em of graph,terminal,label=left:{$R(s)$}] (R){}
		node[right=6em of graph,terminal,label=right:{$C(s)$}] (C){}
		% loop for connections
		foreach \X/\Y [count=\Z] in \GraphInput {
			% bug in pgf, out does not get parsed properly
			[/utils/exec=\pgfmathsetmacro{\myout}{90-(\Z-1)*180/(\mydim-1)}]
			(sX-\Z) edge[amark={$1/s$}] (X-\Z)
			(X-\Z) edge[suppress if 0=\Y,amark'={$\Y$},out=-90,in=-90,looseness=1.25] (sX-\Z)
			\ifnum\Z>\numexpr\mydim/2
			(R) edge[amark'={$\X$},out=\myout,in=180] (sX-\Z)
			(X-\Z) edge[amark'={$1$},out=0,in=180-\myout] (C)
			\else
			(R) edge[suppress if 0=\X,amark={$\X$},out=\myout,in=180] (sX-\Z)
			(X-\Z) edge[amark={$1$},out=0,in=180-\myout] (C)
			\fi
		};
	\end{tikzpicture}
\end{document}
```

![Screen Shot 2020-12-19 at 7.00.27 AM.png](/image?hash=d3583962857fa7e8913d6038b9b4b1b563ff78c942b3adaf9c9f368c7683d9e9)

As for the second part: is this the intended outcome?
```
% define the  matrix 
\edef\mmat{%
	{2,-5,3,0},% <= a missing edge of label "3" should be drawn from X3 to sX1
	{0,-2,2,5},%
	{1,-3,0,7},%
	{-4,0,9,0}%
}
\documentclass[tikz,border=5mm]{standalone}
\usetikzlibrary{calc,decorations.markings,positioning,arrows.meta}
\newif\iflabrev
\begin{document}
    \begin{tikzpicture}[node distance = 15 mm,
        label revd/.is if=labrev,
        label revd/.default=true,
        amark/.style = {
            decoration={             
                markings,   
                mark=at position {0.5} with { 
                    \arrow{stealth},
                    \iflabrev \node[below] {#1};\else \node[above] {#1};\fi
                }
            },
            postaction={decorate}
        }, % make the mark an entry of the \mmat matrix
        pmark/.code n args={2}{%
		\pgfmathtruncatemacro{\myi}{int({\mmat}[\numexpr#1][\numexpr#2])}%
		\typeout{A[\the\numexpr#1,\the\numexpr#2]=\myi}
		\tikzset{suppress if 0=\myi,amark={$\myi$}}% <- changed
		},
        terminal/.style 2 args={draw,alias=ln,circle,inner sep=2pt,label={#1:#2}},
        % semicircle path
        semicircle/.style={to path={let \p1=($(\tikztotarget)-(\tikztostart)$)
            in \ifdim\x1>0pt
              (\tikztostart.north) arc[start angle=180,end angle=0,radius=0.5*\x1]
            \else
              (\tikztostart.south) arc[start angle=0,end angle=-180,radius=-0.5*\x1]
            \fi}},
		suppress if equal/.code 2 args={\edef\mytestA{#1}%
		\edef\mytestB{#2}%
		\ifx\mytestA\mytestB\relax
		\tikzset{opacity=0}
		\fi
		},suppress if 0/.style={suppress if equal={0}{#1}},
        ]
        \pgfmathtruncatemacro{\dimy}{dim({\mmat})} % number of rows
        \pgfmathtruncatemacro{\dimx}{dim({\mmat}[0])} % number of columns
        % create the graph
        \path % R node
        node[terminal={left}{$R(S)$},alias={X-\dimy}] (R) {}
        % loop over matrix entries
        foreach \Y [evaluate=\Y as \X using {int(\dimy-\Y)}]
        in {1,...,\numexpr\dimy-1}
        {node[right=of ln,terminal={below right}{% sX_i node
            $sX_{\X}(s)$}](sX-\X){}
        node[right=of ln,terminal={below right}{% X_i node
            $X_{\X}(s)$}](X-\X){}
        % ege from sX_i to X_i  
        (sX-\X) edge[amark={$\frac{1}{s}$}] (X-\X)
        % edge from X_{i+1} to X_i  (R had an alias)
        (X-\the\numexpr\X+1) edge[pmark={\X-1}{\X}] (sX-\X)
        % semicircle edge from X_i to sX_i
        (X-\X) edge[semicircle,label revd,pmark={\X-1}{\X-1}] (sX-\X)
        % various semicircles, basically connect to all possible older ones
        \ifnum\Y>1
         (R) edge[semicircle,pmark={\X-1}{\dimx-1}] (sX-\X) 
         foreach \Z in {1,...,\numexpr\Y-1} {
          (X-\X) edge[semicircle,pmark={\X+\Z-1}{\X-1}] (sX-\the\numexpr\X+\Z)
		  (sX-\X) edge[semicircle,pmark={\X-1}{\X+\Z-1}] (X-\the\numexpr\X+\Z)
         }
		\else  
		 %(R) edge[semicircle,pmark={\X-1}{\dimx-1}] (sX-\X) 
        \fi
        }% the Y node
        node[right=of ln,terminal={right}{$Y(s)$}](Y){}
        (X-1) edge[pmark={\dimy-1}{0}] (Y)
        % semicircles goint to Y
        foreach \Y [evaluate=\Y as \X using {int(\dimy-\Y)}]
         in {1,...,\numexpr\dimy-2}
        {(X-\X) edge[semicircle,pmark={\dimy-1}{\X-1}] (Y)};
    \end{tikzpicture}
\end{document}
```
![Screen Shot 2020-12-20 at 9.46.24 AM.png](/image?hash=6adf3adf30407a6db4d9a5977e9970b3b10f6de5fe7eff080ebcbe360e80c47a)

Enter question or answer id or url (and optionally further answer ids/urls from the same question) from

Separate each id/url with a space. No need to list your own answers; they will be imported automatically.