# Prepare Greenberger–Horne–Zeilinger state with Quantum Circuit

First, you have to use this package in Julia.

`using Yao`

Now, we just define the circuit according to the circuit image below:

```
circuit = chain(
4,
put(1=>X),
repeat(H, 2:4),
control(2, 1=>X),
control(4, 3=>X),
control(3, 1=>X),
control(4, 3=>X),
repeat(H, 1:4),
)
```

```
nqubits: 4
chain
├─ put on (1)
│ └─ X
├─ repeat on (2, 3, 4)
│ └─ H
├─ control(2)
│ └─ (1,) X
├─ control(4)
│ └─ (3,) X
├─ control(3)
│ └─ (1,) X
├─ control(4)
│ └─ (3,) X
└─ repeat on (1, 2, 3, 4)
└─ H
```

Let me explain what happens here.

## Put single qubit gate X to location 1

we have an `X`

gate applied to the first qubit. We need to tell `Yao`

to put this gate on the first qubit by

`put(4, 1=>X)`

```
nqubits: 4
put on (1)
└─ X
```

We use Julia's `Pair`

to denote the gate and its location in the circuit, for two-qubit gate, you could also use a tuple of locations:

`put(4, (1, 2)=>swap(2, 1, 2))`

```
nqubits: 4
put on (1, 2)
└─ put on (1, 2)
└─ SWAP
```

But, wait, why there's no `4`

in the definition above? This is because all the functions in `Yao`

that requires to input the number of qubits as its first argument could be lazy (curried), and let other constructors to infer the total number of qubits later, e.g

`put(1=>X)`

`(n -> put(n, 1 => X))`

which will return a lambda that ask for a single argument `n`

.

`put(1=>X)(4)`

```
nqubits: 4
put on (1)
└─ X
```

## Apply the same gate on different locations

next we should put Hadmard gates on all locations except the 1st qubits.

We provide `repeat`

to apply the same block repeatly, repeat can take an iterator of desired locations, and like `put`

, we can also leave the total number of qubits there.

`repeat(H, 2:4)`

`(n -> repeat(n, H, 2:4...))`

## Define control gates

In Yao, we could define controlled gates by feeding a gate to `control`

`control(4, 2, 1=>X)`

```
nqubits: 4
control(2)
└─ (1,) X
```

Like many others, you could leave the number of total qubits there, and infer it later.

`control(2, 1=>X)`

`(n -> control(n, 2, 1 => X))`

## Composite each part together

This will create a `ControlBlock`

, the concept of block in Yao basically just means quantum operators, since the quantum circuit itself is a quantum operator, we could create a quantum circuit by composite each part of.

Here, we use `chain`

to chain each part together, a chain of quantum operators means to apply each operators one by one in the chain. This will create a `ChainBlock`

.

```
circuit = chain(
4,
put(1=>X),
repeat(H, 2:4),
control(2, 1=>X),
control(4, 3=>X),
control(3, 1=>X),
control(4, 3=>X),
repeat(H, 1:4),
)
```

```
nqubits: 4
chain
├─ put on (1)
│ └─ X
├─ repeat on (2, 3, 4)
│ └─ H
├─ control(2)
│ └─ (1,) X
├─ control(4)
│ └─ (3,) X
├─ control(3)
│ └─ (1,) X
├─ control(4)
│ └─ (3,) X
└─ repeat on (1, 2, 3, 4)
└─ H
```

You can check the type of it with `typeof`

`typeof(circuit)`

`ChainBlock{4}`

## Construct GHZ state from 00...00

For simulation, we provide a builtin register type called `ArrayReg`

, we will use the simulated register in this example.

First, let's create $|00⋯00⟩$, you can create it with `zero_state`

`zero_state(4)`

```
ArrayReg{1, ComplexF64, Array...}
active qubits: 4/4
```

Or we also provide bit string literals to create arbitrary eigen state

`ArrayReg(bit"0000")`

```
ArrayReg{1, ComplexF64, Array...}
active qubits: 4/4
```

They will both create a register with Julia's builtin `Array`

as storage.

## Feed Registers to Circuits

Circuits can be applied to registers with `apply!`

`apply!(zero_state(4), circuit)`

```
ArrayReg{1, ComplexF64, Array...}
active qubits: 4/4
```

or you can use pipe operator `|>`

, when you want to chain several operations together, here we measure the state right after the circuit for `1000`

times

```
results = zero_state(4) |> circuit |> r->measure(r, nshots=1000)
using StatsBase, Plots
hist = fit(Histogram, Int.(results), 0:16)
bar(hist.edges[1] .- 0.5, hist.weights, legend=:none)
```

GHZ state will collapse to $|0000⟩$ or $|1111⟩$.

*This page was generated using Literate.jl.*