Until such a time as Daftwullie
makes his circuit-drawing library public, here is an answer which more-or-less describes the way in which I draw circuits in TiKZ, with some macros to help make the result more reader-friendly.
Snippet
See below for all of the code used to generate this example: the following commands are just the ones used to draw the gates themselves, and the input and output labels. (This snippet involves macros which I have defined for the purpose of this post, which I also define below.)
% draw circuit
\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];
\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{amssymb}
\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 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}
When you draw a circuit using TiKZ, you will often want to change the spacing a bit. You can do that using macros which are used to define the dimensions of the circuit structure. I arrived at the figures below by trial and error.
% define diagram parameters
\xdef\dy{1.25}
\xdef\dt{0.8}
We now set out some co-ordinates for the wires. I am naming the wires A
, B
, and C
, and name some points on the wires after whole-numbered time slices, such as 0
, 1
, and 2
. Thus the first co-ordinates are A-0
, B-0
, and C-0
.
% define initial positions of the quantum wires
\coordinate (A-0) at (0,0);
\coordinate (B-0) at ($(A-0) + (0,-\dy)$);
\coordinate (C-0) at ($(B-0) + (0,-\dy)$);
I now draw our the wires for the circuit by extending each wire, one time-step at a time, for as many time-steps as I want. Note the use of the macro \t
to define the time-slice, and \u
as representing the previous time-slice.
% define coordinates along each of the wires for all timesteps
\xdef\u{0}
\foreach \t in {0,...,15} {%
\foreach \l in {A,B,C} {%
\coordinate (\l-\t) at ($(\l-\u) + (\dt,0)$);
\draw (\l-\u) -- (\l-\t);
}
\xdef\u{\t}
}
That's the basic structure of the circuit defined. I now place the slashes for your two lower registers, half-way between time-steps 0 and 1 (because that's where they look the best as it turns out).
\node at ($(B-0)!0.5!(B-1)$) {$/$};
\node at ($(C-0)!0.5!(C-1)$) {$/$};
Having done all of this to define the structure of the circuit, I draw the gates, input labels, and output labels for the circuit. Hopefully the commands below are transparent enough.
% draw circuit
\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];
\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 (annotate-1) at ($(A-3) + (0,0.75)$)
{\textit{Phase estimation}};
\node (annotate-a) at ($(C-3) + (0,-1.25)$)
{\textit{(a)}};
\node (annotate-2) at ($(A-7) + (0,0.75)$)
{\textit{$\smash{R(\tilde\lambda^{-1}})$ rotation}};
\node (annotate-b) at ($(C-7) + (0,-1.25)$)
{\textit{(b)}};
\node (annotate-3) at ($(A-11) + (0,0.75)$)
{\textit{Uncompute}};
\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}