• No results found

Denotation of Q wire

Wire Types, Contexts and Patterns In order to interpret circuits as superop-

erators over density matrices, we will also give types, contexts, gates, and patterns algebraic interpretations. For clarity we write J−K for the denotation of a variety of

Qwire objects, which we express via a Coq type class.

Class Denote source target := { denote : source target }. Notation "J x K" := (denote x) (at level 10).

We interpret every wire type as the number of Bit or Qubit wires in that type, soJQubit⊗ (One ⊗ Bit)K=2. Contexts are similarly denoted by the number ofBitor

Qubit wires they type.

⎛ ⎜⎜ ⎜ ⎝ 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 ⎞ ⎟⎟ ⎟ ⎠

Patterns of type Pat W are interpreted as permutation matrices of dimension 2JWK×2JWK. These matrices are constructed via multi-

ple applications of the swap matrix to the right. In the simple case, we swap two qubits via a series of adjacent swaps. For instance

swap_two3 0 2 =(I2⊗swap)(swap⊗I2)(I2⊗swap) swaps the 0th and 2nd qubits in a 3-qubit system.

For more general permutations, we begin by translating the input

pattern into a list:(2,(0,1))becomes[2,0,1], which then becomes[(0,2),(1,0),(2,1)]. This sequence of pairs is then translated into a sequence of swap matrices that ensure that qubit 2is put in the zero position and so forth. In this wayoutput pis interpreted as a reordering operation.

Unitaries Every gate of type Unitary W corresponds to a unitary matrix of dimen- sion2JW2JWK. The following gates are built-in to Qwire, but additional gates may

be added: JXK=(0 1 1 0), JYK=( 0 −i i 0), JZK=( 1 0 0 −1),JHK= 1 √ 2( 1 1 1 −1), JK=( 1 0 0 eiϕ)

We also have Jctrl UK which is equal to the block matrix

(I0 JU0K).

We can prove that every denoted unitary satisfies theis_unitarypredicate defined in the previous section:

Lemma unitary_gate_unitary : ∀ {W} (u : Unitary W), is_unitary JuK.

Gates We can now look at denoting gates in general. We will begin in a simplified

setting, where the gate is being applied to a system of the corresponding size in the correct order (for instance, CNOT being applied to qubits 0 and 1 of a two qubit system). In the unitary case, we simply apply U and its adjoint to the state, written mathematically by

JU uKρ=JuKρJuK† or in Coq as

JU uK ρ = super U ρ

We can give the denotation of the remaining gates in Coq, following the denotation given in Section 4.5:

Definition denote_gate {W1 W2} (g : Gate W1 W2) :

Superoperator 2^JW1K 2^JW2K :=

match g with

| U u ⇒ super JuK | init0 | new0 ⇒ super ∣0⟩

| init1 | new1 ⇒ super ∣1⟩

| meas ⇒ Splus (super ∣0⟩⟨0∣) (super ∣1⟩⟨1∣|) | discard Splus (super 0∣) (super 1∣)

end.

where Splus sums over superoperators.

Gates in Context It takes some work to lift this denotation function to the con-

text of denoting gates in a circuit, where we may have additional unused wires or non-adjacent wires input to one gate. We will begin by giving the denotation for sin- gle qubit unitaries, which we pad with identity matrices before applying them to a

quantum state. For instance, if we want to apply a unitaryU to qubit 3in a 5-qubit system ρ, this amounts to the operation

(I23 ⊗UI21)×ρ×(I23⊗UI21)†, which we write in Coq as

super('I_(2^3) JUK⊗ 'I_(2^1))ρ.

It’s similarly easy to describe the semantics of gates like measurement, which we can pad with identity matrices, or initialization, which we add to the end of the circuit:

Definition apply_meas {n} (k : N) : Superoperator (2^n) (2^n) := Splus (super (Id (2^k) ⊗ ∣0⟩⟨0∣ ⊗ Id (2^(n-k-1))))

(super (Id (2^k) ⊗ ∣1⟩⟨1∣ ⊗ Id (2^(n-k-1)))).

Definition apply_init0 {n} : Superoperator (2^n) (2^(n+1)) :=

super (Id (2^n) ⊗ ∣0⟩).

Here, initializing a ∣0⟩ qubit in the 2 qubit systemρ yields (I4⊗∣0⟩)ρ(I4⊗⟨0∣). What about unitaries with multiple controls? Here things become a bit harder, since we cannot simply pad the unitary on either side, given that the target qubits may not even be adjacent to one another or in the desired order (see, for instance, the gate in Figure 5.2). Instead, we make use of the observation5 that

control U =∣1⟩ ⟨1∣⊗U+∣0⟩ ⟨0∣⊗I

where I is the identity matrix with the same dimensions as U. This expression can easily be padded with the identity in the middle, as in

∣1⟩ ⟨1∣⊗I4⊗U+∣0⟩ ⟨0∣⊗I4⊗I or reversed, as in

U⊗∣1⟩ ⟨1∣+I⊗∣0⟩ ⟨0∣ when the target is above the control.

This gives us a blueprint for applying unitary gates which may have multiple control qubits to arbitrary systems. First we need to know where we will be placing the controls and where we will be placing the single-qubit gate. We put this information into a zipper structure (see Figure 5.2), containing the controls above the unitary, those after it, and the 2×2unitary matrix. For instance, suppose we wished to apply

ctrl (ctrl (ctrl Z))to the control wires0,2,7, and the target wire4in an eight-qubit system: We would construct the zipper ([true;false;true;false], JZK, [false;false ;true]).

Z t f t f Z f f t

Figure 5.2: A ctrl (ctrl (ctrl Z)) gate applied to 0,2,7 and 4, and it’s corre- sponding zipper.

We would then feed this zipper into the following (symmetric) functions:

Fixpoint ctrl_list_to_unitary_l (l r : list B) (u : Square 2) : (Square (2^(length l + length r + 1))) :=

match l with

| false :: l' 'I_ 2 ctrl_list_to_unitary l' r u

| true :: l' ⇒ ∣1⟩⟨1∣ ⊗ ctrl_list_to_unitary l' r u .+ ∣0⟩⟨0∣ ⊗ 'I_ _ | [] ⇒ ctrl_list_to_unitary_r (rev r) u

end.

Fixpoint ctrl_list_to_unitary_r (r : list B) (u : Square 2) : (Square (2^(length r + 1))) :=

match r with

| false :: r' ⇒ ctrl_list_to_unitary_r r' u ⊗ Id 2

| true :: r' ⇒ ctrl_list_to_unitary_r r' u ⊗ ∣1⟩⟨1∣ .+ 'I_ _ ⊗ ∣0⟩⟨0∣

| [] ⇒ u

end.

Note that 'I_ _ infers the correct dimensions for the identity matrix. Note also that the second list is reversed before it is passed to ctrl_list_to_unitary_r, allowing us to read the list from right to left.

In our example, ctrl_list_to_unitary_r[true;false;false]JZK would produce the unitary matrix

(ZI2⊗I2⊗∣1⟩ ⟨1∣)+(I8⊗∣0⟩ ⟨0∣).

Applying ctrl_list_to_unitaryto ([true;false;true;false], Z, [false;false;true ]) would then produce

∣1⟩⟨1∣⊗(I2⊗(∣1⟩⟨1∣⊗(I2⊗(ZI2I2⊗∣1⟩⟨1∣+I8⊗∣0⟩⟨0∣))+∣0⟩⟨0∣⊗I32))+∣0⟩⟨0∣⊗I128 which we could apply to our entire 28×28 density matrix.

Circuits We are now in a position to define the general denotation of the De Bruijn circuits from Section 5.3:

Fixpoint denote_db_circuit {w} padding input (c : DeBruijn_Circuit w) : Superoperator (2^(padding+input)) (2^(padding+JwK)) :=

match c with

| db_output p ⇒ super (pad (padding+input) JpK) | db_gate w1 w2 g p c' ⇒

let input' := (input + Jw2K - Jw1K) in

compose_super (denote_db_circuit padding input' c') (apply_gate g (pat_to_list p))

| db_lift p c' ⇒

let k := get_var p in

Splus

(compose_super

(denote_db_circuit padding (input-1) (c' false)) (super ('I_(2^k) ⊗ ⟨0∣ ⊗ 'I_(2^(input-k-1))))) (compose_super

(denote_db_circuit padding (input-1) (c' true)) (super ('I_(2^k) ⊗ ⟨1∣ ⊗ 'I_(2^(input-k-1)))))

end.

Hereinputis the number of input qubits andpaddingallows us to pad the denotation with identities, which is useful in a number of lemmas.

The denotation ofoutput pis simply the denotation ofp: a reordering of the qubits viaSWAPgates. Applying a gate consists of composing theapply_gateoperation above with the denotation of the rest of the circuit. Finally, lift applies the discard operations

super('I_(2^k) ⊗⟨0∣⊗ 'I_(2^(input−k−1)))) and super ('I_(2^k) ⊗ ⟨1∣⊗ 'I_(2^(input

−k−1)))), takes the denotation of the rest of the circuit, and sums the results.

This gives us a superoperator on density matrices and allows us to verify properties of our circuits.