projekter/yquant

Specifying the qubit input correspondence for multi-qubit gates

Closed this issue · 2 comments

I want to specify the input correspondence for multi-qubit gates, as qiskit does. This picture shows a two-qubit gate U acting on the qubit 4 and qubit 0, with 4 as the first input, and 0 as the second.

image

I wonder if there is a working solution, thanks!

There are several ways to achieve "this". Depending on whether you really want to have an exact graphical representation or just something that might resemble the logic.
Here are a couple of examples of what you can do:
image
Now the code - yes, addressing individual registers more comfortably is something that I wanted to implement more comfortably, but due to my time constraints, this definitely won't come in the next months.

\documentclass[tikz]{standalone}

\usepackage[compat=0.7]{yquant}

\makeatletter
\protected\def\multiidx{\ifdefined\yquant@draw@@idx@multipart\yquant@draw@@idx@multipart\else0\fi}
\makeatother

\begin{document}
   \begin{tikzpicture}
      \begin{yquant}
         [name=q] qubit {$q_{\idx}$} q[5];
         
         box {$\multiidx\quad U$} (q[0,4]);
         
         hspace {2mm} -;
         [label=175:$\protect\the\numexpr1-\multiidx\relax$] box {$U$} (q[0,4]);
         
         subcircuit {
            qubit {$1$} first;
            qubit {$0$} second;
            box {$U$} (-);
         } (q[0,4]);
         
         [seamless] subcircuit {
            qubit {$1$} first;
            qubit {$0$} second;
            box {$U$} (-);
         } (q[0,4]);
         
         [name=myu, inner ysep=12mm] box {\quad$U$} (q);
      \end{yquant}
      \node[anchor=west] at (q-0 -| myu.west) {$1$};
      \node[anchor=west] at (q-4 -| myu.west) {$0$};
   \end{tikzpicture}
\end{document}

A couple of explanations.

  1. First example with the box and putting the multiindex directly inside. Well, this actually showed my that a macro to obtain the current index in a multi-register is currently missing. So here I provided a very hackish version with \multiidx. This is bad and should be properly supported, as \yquant@draw@@idx@multipart is only available at the drawing, not at the measuring stage, so the macro doesn't contain the correct value when measuring how large the text actually is. Here, I just replace it by 0 in this case, which is not too bad for single-digits.
  2. Instead of putting the number into the box, you can of course use a label (here I also showed just one way how to turn the 0, 1 into 1, 0; you can use anything LaTeX offers for the index conversion. I put the label at 175°, which means to the left and slightly above. To make some extra room, I also put a little bit of space before.
  3. Maybe you don't like how the box is split among multiple registers. This is yquant's way of demonstrating that the intermediate registers are not affected. But you can instead put them into a subcircuit, then the box only knows about the registers that you declare in the subcircuit. You can also put additional initializers there indicating the positions. This is probably the best way if you have multiple operations in a row that always act on this subset. But the style is of course a bit different: you're really dealing with an entire subcircuit here.
  4. If you just don't like the border lines, you can make the subcircuit seamless. What still remains is that the lines of the unaffected registers will stop at the (now invisible) subcircuit boundary, they are not part of the subcircuit.
  5. Finally, coming visually closest to what you want, but this requires a lot of manual intervention. As you see, I named all qubit registers upon creation, and I also name the box. Additionally, I declare the box to act on all registers of q, not just the first and last, as this produces the visual impression that you want. I add some space to the left, shifting the U to the right. After the circuit, I put nodes containing the labels at the exact positions that I want - that is, the horizontal position of the registers and the vertical "west" anchor of the box. Finally, the worst part is the inner ysep. The box doesn't know about the labels that you're about to put at this position, therefore it will be slightly too small for a good visual impression. The labels will clash with the border. So you'll have to either decrease the font size of the labels (easily possible), shift them slightly down and up (also easy, but not so nice visually), or you have to increase the size of the box. But this is not easily possible... yquant will calculate this size at a very late stage, as it has to figure out how large all the registers will be in the first pass, then in a second pass distribute the vertical positions appropriately and then also take care of multi-registers, whose space is somewhat shared among various registers. This is a very complicated process. You can of course brute-force overwrite yquant by manually specifying an addition vertical inner separation that the U has to have from the border. But how large this separation is, you'll have to figure out manually. And as your circuit grows, yquant might change the vertical positions of the registers, so you'll have to work this out again. Best to only do it at the very end and up to this stage not have any inner ysep at all (as this value will then also influence the vertical positioning). But yes, this is quite hackish. Without the necessary height adjustment, it wouldn't even be so bad...

You might even think to automate the last part in your own gate using \yquantdefinegate.

Thanks for the solution! And thanks for this great work! I have introduced this package to my group, and many of them have tried it and really like it. quantikz really drives me crazy.