Prepare Greenberger–Horne–Zeilinger state with Quantum Circuit

# Prepare Greenberger–Horne–Zeilinger state with Quantum Circuit

First, you have to use this package in Julia.

using Yao, Yao.Blocks

Then let's define the oracle, it is a function of the number of qubits. The circuit looks like this:

n = 4
circuit(n) = chain(
n,
put(1=>X),
repeat(H, 2:n),
control(2, 1=>X),
control(4, 3=>X),
control(3, 1=>X),
control(4, 3=>X),
repeat(H, 1:n),
)
circuit (generic function with 1 method)

Let me explain what happens here. Firstly, we have an X gate which is applied to the first qubit. We need decide how we calculate this numerically, Yao offers serveral different approach to this. The simplest one is to use put(n, ibit=>gate) to apply a gate on the register. The first argument n means the number of qubits, it can be lazy evaluated.

put(n, 1=>X) == put(1=>X)(n)
true

If you wanted to apply a two qubit gate,

put(n, (2,1)=>CNOT)
Total: 4, DataType: Complex{Float64}
put on (2, 1)
└─ CNOT gate

However, this kind of general apply is not as efficient as the following statement

mat(put(n, (2,1)=>CNOT)) ≈ mat(control(n, 2, 1=>X))
true

This means there is a X gate on the first qubit that is controled by the second qubit. Yao.jl providea a simple API mat to obtain the matrix representation of a block SUPER efficiently. This distinct feature helps users debug their quantum programs easily, and is equally useful in time evolution and ground state solving problems.

For a multi-controlled gate like Toffoli gate, the construction is quite intuitive

control(n, (2, 1), 3=>X)
Total: 4, DataType: Complex{Float64}
control(2, 1)
└─ (3,)=>X gate

Do you know how to construct a general multi-control, multi-qubit gate? Just have a guess and try it out!

In the begin and end, we need to apply H gate to all lines, you can do it by repeat, For some specific types of gates such as X, Y and Z, applying multiple of them can be as efficient as applying single gate.

The whole circuit is a chained structure of the above blocks. And we actually store a quantum circuit in a tree structure.

circuit
circuit (generic function with 1 method)

After we have an circuit, we can construct a quantum register, and input it into the oracle. You will then receive this register after processing it.

r = apply!(register(bit"0000"), circuit(4))
DefaultRegister{1, Array{Complex{Float64},2}}
active qubits: 4/4

Let's check the output:

statevec(r)
16-element Array{Complex{Float64},1}:
0.7071067811865471 + 0.0im
0.0 + 0.0im
0.0 + 0.0im
0.0 + 0.0im
0.0 + 0.0im
0.0 + 0.0im
0.0 + 0.0im
0.0 + 0.0im
0.0 + 0.0im
0.0 + 0.0im
0.0 + 0.0im
0.0 + 0.0im
0.0 + 0.0im
0.0 + 0.0im
0.0 + 0.0im
-0.7071067811865471 + 0.0im

We have a GHZ state here, try to measure the first qubit

measure(r, nshot=1000)
1000-element Array{Int64,1}:
0
15
0
15
15
15
0
15
15
0
⋮
0
15
15
15
15
15
15
15
15

GHZ state will collapse to $|0000\rangle$ or $|1111\rangle$ due to entanglement!