projekter/yquant

Creating block-controlled gate

Closed this issue · 2 comments

I am trying to draw a gate that are controlled by a block, which represents complicated conditions on the control register.

The following circuit is an example:
image

Is there is a solution to draw such circuit? Thanks!

Let me give two solutions. The first one is the one I would prefer, which makes used of the deferred-control apparatus. Currently, this is available only for the measure gate: You can tell the measure gate that it should not appear where you draw it, but rather that it should replace the next control knob at the given register. This is for the common way to have a measurement gate that directly goes into the control line.
What you now need is a new gate that uses this behavior, but that instead does what box does. This is an advanced (but still quite simple) gate declaration - basically, you just have to copy the gate declaration from box and replace \yquant@prepare by \yquant@prepare@injection and you are done.

\documentclass[tikz]{standalone}

\usepackage[compat=0.6]{yquant}
\yquantset{
   operators/every box/.append style={rounded corners},
   operators/every control box/.style={/yquant/operators/every rectangular box}
}
\makeatletter
\yquant@langhelper@declare@command@uncontrolled%
   {controlbox}%
   \yquant@register@get@allowmultitrue%
   {%
      \expandafter\yquant@prepare@injection%
         \expandafter{\yquant@lang@attr@value}%
         {/yquant/operators/every control box}%
   }
\makeatother

\begin{document}
   \begin{tikzpicture}
      \begin{yquant}[register/separation=2mm]
         qubit {selection\\[-1mm]register} sel;
         qubit {control\\[-1mm]register} ctrl;
         qubit {state\\[-1mm]register} state;
         
         slash -;
         controlbox {$B$} ctrl;
         box {binary-controlled} sel | ctrl;
         controlbox {$U$} state;
         box {binary-controlled} sel, ctrl | state;
         controlbox {$B^\dagger$} ctrl;
         box {binary-controlled} sel | ctrl;
      \end{yquant}
   \end{tikzpicture}
\end{document}

I additionally appended the rounded corners to every box, as this seems to be your preference.
All that you then do is to first put the control box to the register that is supposed to contain the control, then use an ordinary controlled box next.

A second way that "works" without a new gate declaration is to abuse controls. You can define a new style that essentially makes the control a zero-width no-content thing. Then, you can put the control in the same way as where a gate already is (which of course is semantically wrong, but yquant will not check for this). Since a control is present, yquant will draw the control line from top to bottom, as we want it. The varying corner styles can be mimicked with only at, and the varying contents by querying \idx.

\documentclass[tikz]{standalone}

\usepackage[compat=0.6]{yquant}

\yquantset{hidectrl/.style={
   /yquant/every negative control/.style={fill=none, draw=none, radius=0pt}
}}

\begin{document}
   \begin{tikzpicture}
      \begin{yquant}[register/separation=2mm]
         qubit {selection\\[-1mm]register} sel;
         qubit {control\\[-1mm]register} ctrl;
         qubit {state\\[-1mm]register} state;
         
         slash -;
         box {$G_\mu$} sel;
         [operator style={only at={0}{rounded corners}}, hidectrl]
         box {\Ifcase\idx binary-controlled\Or $B$\Fi} sel, ctrl ~ sel;
         [operator style={only at={0-1}{rounded corners}}, hidectrl]
         box {\Ifnum\idx<2 binary-controlled\Else $U$\Fi} - ~ sel;
         [operator style={only at={0}{rounded corners}}, hidectrl]
         box {\Ifcase\idx binary-controlled\Or $B^\dagger$\Fi} sel, ctrl ~ sel;
      \end{yquant}
   \end{tikzpicture}
\end{document}

Naturally, this is quite an abuse of what you can do, so I wouldn't go for this unless really necessary.

A third way would be to define a new gate that does not merge between multi-registers, then put everything in a multi-register and rely on the internal multi-index position as I showed in a recent issue to query where we are and conditionally put text in. I won't give an example for this.

Thanks for the solution! Just tried out the first solution and the second solution, they both work!