How to re-create the following circuit image?

What would be the best way to re-create the following image of the HHL quantum circuit without compromising on image quality (the image is from this review paper)? Using qasm2circ I can create the basic circuit. But I don't know any good program/software which will help to produce the labels of the various components and also the nice transparent boxes emphasizing the 3 main steps.

FWIW, I had contacted the corresponding author last week asking about the software they used to generate the image (and also whether the image has any associated copyright license), but haven't received any response so far, which is why I am asking here.

• Can't you just add those boxes later with inkscape or sth. the like? – Norbert Schuch Aug 21 '18 at 18:16
• @NorbertSchuch I'm not sure Inkspace would allow labels like $R(\lambda^{-1})$ i.e. containing LaTeX expressions. – Sanchayan Dutta Aug 21 '18 at 18:18
• It does. ________ – Norbert Schuch Aug 21 '18 at 18:20
• @NorbertSchuch I see. Thanks. I haven't used Inkscape before, so I didn't know. – Sanchayan Dutta Aug 21 '18 at 18:21

Edit —

1. I've revised this answer to make some small improvements in the commands, to tidy up the commands for drawing the wires for instance, because it seemed worthwhile.

2. Flattering as it is to have this answer be the accepted one for the time being, I think I should point out that the quantikz package (see Daftwullie's answer below) and the qpic package (as pointed out in cnada's answer below) are both libraries with reasonably complete interfaces, and so better for people looking for a quick and simple solution. The code below is probably more suitable for people who are comfortable with TiKZ, and might like to tweak their circuit diagrams with TiKZ commands, but who wouldn't mind having some macros to streamline drawing their diagrams. — Nice as it might be to, for the moment I have no ambition to write a LaTeX package to make these macros available with a nice interface for all purposes (but anyone else who would like to is welcome if they give me some of the credit).

Snippet

See below for all of the code used to generate this example: the following commands are just the ones used to draw the circuit itself. (This snippet involves macros which I have defined for the purpose of this post, which I also define below.)

% define initial positions of the quantum wires
\xdef\dy{1.25}
\defwire (A) at (0);
\defwire (B) at ({-\dy});
\defwire (C) at ({-2*\dy});
% draw wires
\xdef\dt{0.8}
\drawwires [\dt] (15);
\node  at ($(B-0)!0.5!(B-1)$) {$/$};
\node  at ($(C-0)!0.5!(C-1)$) {$/$};
% draw gates
\gate     (B-2)         [H^{\otimes n}];
\ctrlgate (B-3) (C-3)   [U];
\virtgate (A-3);
\gate     (B-4)         [\mathit{FT}^\dagger];
\ctrlgate (B-7) (A-7)   [R];
\virtgate (C-7);
\gate     (B-10)        [\mathit{FT}];
\ctrlgate (B-11) (C-11) [U^\dagger];
\gate     (B-12)        [H^{\otimes n}];
\virtgate (A-12);
\meas     (A-14)        [Z];
% draw input and output labels
\inputlabel  (A-0)  [\lvert 0 \rangle];
\inputlabel  (B-0)  [\lvert 0 \rangle^{\otimes n}];
\inputlabel  (C-0)  [\lvert b \rangle];
\outputlabel (A-15) [\lvert 1 \rangle];
\outputlabel (B-15) [\lvert 0 \rangle^{\otimes n}];
\outputlabel (C-15) [\lvert x \rangle];

Result Preamble

You will need a pre-amble which contains at least the amsmath package, as well as the tikz package. You may not need all of the tikz libraries below, but they don't hurt. Be sure to include the commands involving layers.

\documentclass[a4paper,10pt]{article}

\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{shapes,arrows,calc,positioning,fit}
\pgfdeclarelayer{background}
\pgfsetlayers{background,main}

For the purposes of this post, I've defined some ad-hoc macros to make reading the coded circuit easier for public consumption. (The macro format is not exactly good LaTeX practise, but I define them this way in order for the syntax to be more easily read and for it to stand out.) The parameters for dimensions in these gates were chosen to look good in your sample-circuit, and were found by trial-and-error: you can change them to change the appearance of your circuit.

The first is a simple macro to draw a gate.

\def\gate (#1) [#2]{%
\node [
draw=black,fill=white, inner sep=0pt,
minimum width=2.5em, minimum height=2em, outer sep=1ex
] (#1) at (#1) {$#2$}%
}

The second is a macro to draw an 'invisible' gate. This is not really a command which is important for the circuit itself, but helps for the placement of background frames.

\def\virtgate (#1){%
\node [
draw=none, fill=none,
minimum width=2.5em, minimum height=2em, outer sep=1ex
] (#1) at (#1) {};
}

The third is a macro to draw a controlled gate. This command works well enough for your example circuit, but doesn't allow you to draw a CNOT. (Exercise for the reader proficient in TiKZ: make a \CNOT command.)

\def\ctrlgate (#1) (#2) [#3]{%
\filldraw [black] (#1) circle (2pt) -- (#2);
\gate (#2) [#3]
}

The fourth is a macro to draw a "measurement" box. I think it is perfectly reasonable to want to specify an explicit basis or observable for the measurement, so I allow an argument to specify that.

\def\meas (#1) [#2]{%
\node [
draw=black, fill=white, inner sep=2pt,
label distance=-5mm, minimum height=2em, minimum width=2em
] (meas) at (#1) {};
\draw ($(meas.south) + (-.75em,1.5mm)$) arc (150:30:.85em);
\draw ($(meas.south) + (0,1mm)$) -- ++(.8em,1em);
\node [
anchor=north west, inner sep=1.5pt, font=\small
] at (meas.north west) {#2};
}

I define two short macros to produce the labels for the inputs and outputs of wires.

\def\inputlabel (#1) [#2]{%
\node at (#1) [anchor=east] {$#2$}
}
\def\outputlabel (#1) [#2]{%
\node at (#1) [anchor=west] {$#2$}
}

The macros above are all looking for co-ordinates at which to place the gates. I also define macros to define "wires", which have regularly spaced co-ordinates where gates can be located. The first is a macro which allows you to define a named wire (such as A, B, x3, etc.) and its vertical position in the circuit diagram (these diagrams are left-to-right by default, which you can change most easily using the rotate option of the tikzpicture environment.)

\def\defwire (#1) at (#2){%
\ifx\qmwires\empty
\edef\qmwires{#1}%
\else
\edef\qmwires{\qmwires,#1}%
\fi
\coordinate (#1-0) at ($(0,#2)$)%
}

Having defined a collection of wires, the following command then draws all of them, starting from the same left-most starting point and ending at the same right-most ending point, with increments by a fixed amount (given in the square brackets) and for a given number of time slices. This defines a sequence of 'time-slice' co-ordinates for each wire: for a wire A, it defines the co-ordinates A-0, A-1, and so forth up until A-t (where t is the value of the second argument).

\def\drawwires [#1] (#2);{%
\xdef\u{0}
\foreach \t in {0,...,#2} {%
\foreach \l in \qmwires {%
\coordinate (\l-\t) at ($(\l-\u) + (#1,0)$);
\draw (\l-\u) -- (\l-\t);
}
\xdef\u{\t}
}
}

The final macro is one to draw a background frame for different stages in your circuit. It takes an argument specifying which gates (including the invisible virtual 'gates') are meant to belong to the frame.

\def\bgframe [#1]{%
\node [%
draw=black, fill=yellow!40!gray!30!white, fit=#1
] {}%
}

The circuit diagram itself

Now to begin drawing your circuit.

\begin{document}
\begin{tikzpicture}

We start by defining the relative positions of the wires. (For convenience, I do this using a macro to define the spacing between them, that I can quickly change to adjust the spacing.) Below, I define three wires: A, B, and C.

\let\qmwires\empty
% define initial positions of the quantum wires
\xdef\dy{1.25}
\defwire (A) at (0);
\defwire (B) at ({-\dy});
\defwire (C) at ({-2*\dy});

We now draw the circuit, using the command to draw the wires and define the co-ordinates on the wire, and placing gates independently of one another according to those co-ordinates.

% draw circuit
\xdef\dt{0.8}
\drawwires [\dt] (15);
\node  at ($(B-0)!0.5!(B-1)$) {$/$};
\node  at ($(C-0)!0.5!(C-1)$) {$/$};
\gate     (B-2)         [H^{\otimes n}];
\ctrlgate (B-3) (C-3)   [U];
\virtgate (A-3);
\gate     (B-4)         [\mathit{FT}^\dagger];
\ctrlgate (B-7) (A-7)   [R];
\virtgate (C-7);
\gate     (B-10)        [\mathit{FT}];
\ctrlgate (B-11) (C-11) [U^\dagger];
\gate     (B-12)        [H^{\otimes n}];
\virtgate (A-12);
\meas     (A-14)        [Z];
% draw input and output labels
\inputlabel  (A-0)  [\lvert 0 \rangle];
\inputlabel  (B-0)  [\lvert 0 \rangle^{\otimes n}];
\inputlabel  (C-0)  [\lvert b \rangle];
\outputlabel (A-15) [\lvert 1 \rangle];
\outputlabel (B-15) [\lvert 0 \rangle^{\otimes n}];
\outputlabel (C-15) [\lvert x \rangle];

Annotations for the circuit

The rest of the circuit diagram is literally commentary. We can do this using a combination of plain-old TiKZ nodes, and the \bgframe macro which I defined above. (Annotations are a little less predictable, so I don't have a good way of making them as systematic as the earlier parts of the circuit, so general TiKZ commands are a reasonable approach unless you know how to make your annotations uniform.)

First the annotations for the stages of the circuit:

% draw annotations
\node [minimum height=4ex] (annotate-1) at ($(A-3) + (0,1)$)
{\textit{Phase estimation}};
\node [minimum height=4ex] (annotate-2) at ($(A-7) + (0,1)$)
{\textit{$\smash{R(\tilde\lambda^{-1}})$ rotation}};
\node [minimum height=4ex] (annotate-3) at ($(A-11) + (0,1)$)
{\textit{Uncompute}};
\node (annotate-a) at ($(C-3) + (0,-1.25)$)  {\textit{(a)}};
\node (annotate-b) at ($(C-7) + (0,-1.25)$)  {\textit{(b)}};
\node (annotate-c) at ($(C-11) + (0,-1.25)$) {\textit{(c)}};

Next, the annotations for the registers, at the input:

\node (A-in-annotate) at ($(A-0) + (-3em,0)$) [anchor=east]
{\parbox{4.5em}{\centering  Ancilla register $S$ }};
\node (B-in-annotate) at ($(B-0) + (-3em,0)$) [anchor=east]
{\parbox{4.5em}{\centering Clock \\ register $C$ }};
\node (C-in-annotate) at ($(C-0) + (-3em,0)$) [anchor=east]
{\parbox{4.5em}{\centering Input \\ register $I$ }};

Finally, the frames for the stages of the circuit.

% draw frames for stages of the circuit
\begin{pgfonlayer}{background}
\bgframe [(annotate-1)(B-2)(B-4)(C-3)];
\bgframe [(annotate-2)(B-7)(C-7)];
\bgframe [(annotate-3)(B-10)(B-12)(C-11)];
\end{pgfonlayer}

And that's the end of the circuit.

\end{tikzpicture}
\end{document}
• Do you mind if I reuse your code and rendered image ditto (with attribution of course)? I need to make several diagrams like this for a paper I'm writing. – Sanchayan Dutta Aug 22 '18 at 16:01
• @Blue: go ahead! Please let me know afterwards if you extend the macros in a way which you find useful. :-) – Niel de Beaudrap Aug 22 '18 at 16:03
• Sure, I will :) – Sanchayan Dutta Aug 22 '18 at 16:04
• it would be great if you could also provide the full minimal working example in an easily copyable format (for example having it as a github gist)! – glS Aug 22 '18 at 17:27
• N.B. I have now fixed the problems with the box heights in my latest edit. – Niel de Beaudrap Sep 7 '18 at 12:17

I always used to use qcircuit but, as it happens, I've recently been developing a tikz library to do the job, which has some added flexibility. The package will be available at the following DOI: 10.17637/rh.7000520. First, I load my library in the document preamble

\usetikzlibrary{quantikz}

Then I typeset the circuit with

\begin{tikzcd}
\lstick{Ancilla \ket{0}\\ register $S$} & \qw & \qw\gategroup[background,style={fill=gray!20,rounded corners},wires=3,steps=3]{Phase estimation} & \qw & \qw & \qw &  \gate{R}\gategroup[background,style={fill=gray!20,rounded corners},wires=3,steps=1]{$R(\tilde\lambda^{-1})$ rotation} & \qw & \qw\gategroup[background,style={fill=gray!20,rounded corners},wires=3,steps=3]{Uncompute}  & \qw & \qw & \meter{} & \rstick{\ket{1}} \qw \\
\lstick{Clock $\ket{0}^{\otimes n}$\\ register $C$}& \qwbundle & \gate{H^{\otimes n}} & \ctrl{1} & \gate{FT^\dagger} & \hphantomgate{}\qw & \ctrl{-1} & \hphantomgate{}\qw & \gate{FT} & \ctrl{1} & \gate{H^{\otimes n}} & \qw & \rstick{$\ket{0}^{\otimes n}$}\qw \\[1em]
\lstick{Input \ket{b} \\ register $I$}&\qwbundle& \qw&\gate{U}&\qw& \qw & \qw&\qw&\qw&\gate{U}&\qw&\qw &\rstick{\ket{x}}\qw
\end{tikzcd}
• Where can I find documentation for quantikz? – pyramids Aug 22 '18 at 5:21
• @pyramids It's now available through figshare. Please see the link in my answer. – DaftWullie Aug 23 '18 at 10:11

I know there is the Latex package qcircuit

But I am not sure about how they did the boxes for the 3 parts a,b,c. Maybe some image tool for drawing them.

Edit : Found this discussion where one admitted using Tikz for drawing similar images

Edit 2 : I found this little tool called qpic which can help you build fancy quantum circuits. You will be able to do it easily I suppose.

• Drawing the quantum circuit is not a problem. I already used qasm2circ to draw that. The nice boxes and text labels are what I need. – Sanchayan Dutta Aug 21 '18 at 16:42
• Then use Tikz. Sounds like you can do many things like using dashed separators in red for stating that it is in 3 parts. tex.stackexchange.com/questions/199683/… – cnada Aug 21 '18 at 16:58
• I'm not sure I will adopt it myself, but I really like the looks of qpic. Someone put some thought into that! – Niel de Beaudrap Sep 7 '18 at 10:57

According to the meta-information in the PDF of the figure, it has been created with PowerPoint:

\$ pdfinfo HHL_circuit.pdf
Title:          HHL_circuit
Creator:        PowerPoint
Producer:       Mac OS X 10.13.2 Quartz PDFContext
[...]

(You can download paper sources from the arxiv by choosing "other formats".)
{"ft_lang_label":"__label__en","ft_lang_prob":0.8128265,"math_prob":0.95420796,"size":9161,"snap":"2019-43-2019-47","text_gpt3_token_len":2895,"char_repetition_ratio":0.1241673,"word_repetition_ratio":0.152,"special_character_ratio":0.32954916,"punctuation_ratio":0.12904997,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.99138576,"pos_list":[0,1,2,3,4,5,6],"im_url_duplicate_count":[null,10,null,10,null,10,null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2019-10-16T11:49:33Z\",\"WARC-Record-ID\":\"<urn:uuid:f2d4da85-8595-4ab9-bd8a-8d97f967695d>\",\"Content-Length\":\"184360\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:10e88937-1d2e-45ca-baaf-4278d1cc9ea1>\",\"WARC-Concurrent-To\":\"<urn:uuid:8068e7db-f0a6-43ae-b14d-616463a05c63>\",\"WARC-IP-Address\":\"151.101.193.69\",\"WARC-Target-URI\":\"https://quantumcomputing.stackexchange.com/questions/4066/how-to-re-create-the-following-circuit-image\",\"WARC-Payload-Digest\":\"sha1:N5P6BSW6XI6FZPLALT5NTTGND3AOONZA\",\"WARC-Block-Digest\":\"sha1:IF566WKOKS4IXMALGKONQVYPAIRJGOJE\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2019/CC-MAIN-2019-43/CC-MAIN-2019-43_segments_1570986668569.22_warc_CC-MAIN-20191016113040-20191016140540-00222.warc.gz\"}"}