Note

Click here to download the full example code

# Introduction to Quantum Gates and Circuits

The building blocks of quantum algorithms are gates, cycles, and circuits. A gate is
an operation that can act on one or more qudits. A cycle is a single step of an
algorithm, which contains gates and qudit labels specifying which qudits those gates
act on. A circuit is a sequence of cycles that ultimately is run on a device. In this
tutorial, we focus on 2-level systems, or *qubits*. A simple diagram of a circuit
acting on qubits is included below to show how these building blocks fit together.

The circuit in the figure above creates the 3-qubit GHZ state, \(\frac{1}{\sqrt{2}}(\ket{000}+\ket{111})\). We now show how to make the corresponding GHZ circuit in True-Q™.

The first step in constructing a circuit is generally to define its gates. In this
example however, we can simply use True-Q™’s built-in gates to implement the circuit.
You can refer to the Configuration page for details on
True-Q™’s methods for gate construction; these will be helpful when constructing
gates that are less standard. The two gates we will use are the Hadamard gate
(available through the `trueq.Gate.h`

object) and the controlled-Z gate
(`trueq.Gate.cz`

).

Next, we can construct the cycles that make up this circuit as follows:

```
import trueq as tq
cycle1 = tq.Cycle({0: tq.Gate.h, 1: tq.Gate.h, 2: tq.Gate.h})
cycle2 = tq.Cycle({(0, 1): tq.Gate.cz})
cycle3 = tq.Cycle({(0, 2): tq.Gate.cz})
cycle4 = tq.Cycle({1: tq.Gate.h, 2: tq.Gate.h})
```

In the above code snippet, the qubits are labeled 0 through 2 and the qubits each gate
acts on in a given cycle are specified before the gate is given as `(labels):gate`

.
Next we construct the circuit as a chronologically ordered list of cycles:

```
circuit = tq.Circuit([cycle1, cycle2, cycle3, cycle4])
```

To generate a visual representation of this circuit as we have seen above, we can call
the `draw()`

method:

```
circuit.draw()
```

This generates an interactive circuit visualization that allows you to inspect the circuit’s individual operations by hovering over the gates with your mouse.

If we want to perform measurements at the end of the circuit, we can append a cycle of
measurements using the `measure_all()`

method:

```
circuit.measure_all()
circuit.draw()
```

## Executing a circuit using the simulator

To inspect the action that a certain circuit has on a given number of qubits, we can use True-Q™’s built-in simulator to simulate the results. We can initialize an ideal simulator as follows:

```
sim = tq.Simulator()
```

The simulator assumes the initial state is \(\ket{0}^{\otimes n}\) by default, but
can be customized to have a different initial state. Noise models can also be added to
the simulator to investigate how circuits behave when run on error-prone quantum
devices. By calling the `run()`

method, you can simulate the
circuit on the simulator we initialized above:

```
sim.run(circuit, n_shots=100)
```

The `n_shots`

keyword specifies how many times we want the results to be sampled
from the final quantum state after running this circuit. If we set it to infinity,
(e.g. `float("inf")`

or `numpy.inf``

) then we obtain the exact simulated
probabilities.

When a circuit is run on a simulator, the results are written to the
`circuit.result`

attribute. To view them, we can can simply print them out:

```
circuit.results
```

```
Results({'000': 47, '111': 53})
```

We expect the output to contain only `000`

and `111`

since these are the only
basis states that are populated in a GHZ state, and they should occur with roughly
equal probability. However, since each run has a 50/50 probability of returning either
result, the results will not necessarily be divided evenly between the two outcomes.

In addition to printing the results of a simulation, we can also visualize them
using True-Q™’s plotting capabilities. To generate a simple histogram, you can call
the `plot()`

method:

```
circuit.results.plot()
```

**Total running time of the script:** ( 0 minutes 0.107 seconds)