# QWorld Bronze: First Quantum Programs by Qiskit

(01/06/2021)

## First Quantum Programs by Qiskit

Watch Lecture

In principle, every reversible classical program (i.e., a classical program containing only reversible operators) is also a quantum program.

NOT operator is a classical reversible operator, and so we can design quantum programs by using NOT operator.

For our quantum programs, we will design quantum circuits. In this notebook, we will use Qiskit library.

As a warm-up example, here we design a circuit with a single quantum bit (qubit).

We highlight the details on designing quantum circuits along with our codes.

### Design a circuit

#
# A quantum circuit is composed by quantum and classical bits in Qiskit.
#

# here are the objects that we use to create a quantum circuit in qiskit
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit

# we use a quantum register to keep our quantum bits.
q =  QuantumRegister(1,"qreg")# in this example we will use a single quantum bit
# the second parameter is optional

# To retrieve an information from a quantum bit, it must be measured. (More details will appear.)
#     The measurement result is stored classically.
#     Therefore, we also use a classical regiser with classical bit(s)
c = ClassicalRegister(1,"creg")# in this example we will use a single classical bit
# the second parameter is optional

# now we can define our quantum circuit
# it is composed by a quantum and a classical registers
qc = QuantumCircuit(q,c)

# we apply operators on quantum bits
# operators are called as gates
# we apply NOT operator represented as "x" in qiskit
# operator is a part of the circuit, and we should specify the quantum bit as its parameter
qc.x(q[0])# (quantum) bits are enumerated starting from 0
# NOT operator or x-gate is applied to the first qubit of the quantum register

# measurement is defined by associating a quantum bit to a classical bit
qc.measure(q[0],c[0])
# after the measurement, the observed value of the quantum bit is stored in the classical bit

# we run our codes until now, and then draw our circuit
print("The design of the circuit is done.")

Visualize the circuit

Visualizing quantum circuits are always helpful to see the whole program at once.

We use two different circuit drawing methods of Qiskit.

# in Qiskit, the circuit object has a method called "draw"
# the default drawing method uses ASCII art

# let's draw our circuit now
qc.draw()

# re-execute this cell if you DO NOT see the circuit diagram

# we can draw the same circuit by using matplotlib
qc.draw(output='mpl')

As seen explicitly in the first diagram, each quantum or classical bit is set to value/state 0 at the beginning.

As a convention in quantum computing (mechanics), state 0 is denoted as $\ket{0}$. This notation is called as ket.

Each quantum bit is represented as a single straight line. Each classical bit is represented as a double straight line. You may think of them as wires.

The x-gate and the measurement operators are shown as boxes. Remark that the measurement operator is represented differently in the diagrams. Both are used in the literature.

The state of the quantum bit is expected to be $\ket{1}$ after the operator. So, the value of the classical bit after the measurement is expected to be 1.

### Execute the circuit

A quantum program can be executed on a real quantum computer or a local classical simulator or a simulator in the cloud. Here we use a local classical simulator provided by Qiskit and so our results will be (almost) accurate.

Remark that the existing real quantum computers are still noisy and so the observed results will be inaccurate.

# we use the method "execute" and the object "Aer" from qiskit library
from qiskit import execute, Aer

# we create a job object for execution of the circuit
# there are three parameters
#     1. mycircuit
#     2. backend on which it will be executed: we will use local simulator
#     3. how many times it will be executed, by default it is 1024
job = execute(qc,Aer.get_backend('qasm_simulator'),shots=1024)

# we can get the result of the outcome as follows
counts = job.result().get_counts(qc)
print(counts)# counts is a dictionary

That is, the outcome 1 is measured 1024 times.

The output is composed by pairs, and each pair shows (i) the measurement outcome and (ii) its frequency.

After executing the above program on a real quantum computer by using IBM Quantum Experience, we obtained the value of '0' 62 times and the value of '1' 962 times.

# we can show the result by using histogram as follows
from qiskit.visualization import plot_histogram
plot_histogram(counts)

Quantum assembly language

In the above execution, we used "qasm_simulator". Here "qasm" stands for Open Quantum Assembly Language. Our circuit is converted to qasm code before executing on simulators or real quantum computers.

Wikipedia (Feb 18, 2020): Qasm is an intermediate representation for quantum instructions. The language was first described in a paper published in July 2017, and source code was released as part of IBM's Quantum Information Software Kit (Qiskit) for use with their IBM Q Experience cloud quantum computing platform. The language has similar qualities to traditional hardware description languages such as Verilog.

#print qasm code of our program
print(qc.qasm())

### A quantum circuit with more quantum bits

We design a new quantum circuit with four quantum bits.

#
# A quantum circuit with four quantum and classical bits
#

# import all objects and methods at once
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit, execute, Aer

# define quantum and classical registers and then quantum circuit
q2 = QuantumRegister(4,"qreg")
c2 = ClassicalRegister(4,"creg")
qc2 = QuantumCircuit(q2,c2)

# apply x-gate to the first quantum bit twice
qc2.x(q2[0])
qc2.x(q2[0])

# apply x-gate to the fourth quantum bit once
qc2.x(q2[3])

# apply x-gate to the third quantum bit three times
qc2.x(q2[2])
qc2.x(q2[2])
qc2.x(q2[2])

# apply x-gate to the second quantum bit four times
qc2.x(q2[1])
qc2.x(q2[1])
qc2.x(q2[1])
qc2.x(q2[1])

# define a barrier (for a better visualization)
qc2.barrier()

# if the sizes of quantum and classical registers are the same, we can define measurements with a single line of code
qc2.measure(q2,c2)
# then quantum bits and classical bits are associated with respect to their indices

# run the codes until now, and then draw our circuit
print("The design of the circuit is done.")

qc2.draw(output='mpl')
# re-execute this cell if the circuit diagram does not appear

The default order of quantum bits from top to down is

.

The order can be reversed as shown below.

# by setting parameter "reverse_bits" to "True", the order of quantum bits are reversed when drawing

qc2.draw(output='mpl',reverse_bits=True)
# re-execute this cell if the circuit diagram does not appear

Guess the outcome by checking the circuit.

Then, compare your guess with the result obtained after executing our circuit 100 times.

job = execute(qc2,Aer.get_backend('qasm_simulator'),shots=100)
counts = job.result().get_counts(qc2)
print(counts)

Qiskit combines the four quantum bits in the following order:

Then, each outcome is read in the same order.

The outcome is a binary number, and so the first digit is expected to be the most significant bit and the last digit is expected to be the least significant bit.

For example, $13=1*2^{3}+1*2^{2}+0*2^{1}+1*2^{0}$​, which is equal to in binary.

In this case, , , , and .

### Pick a random number in python

In the following task, you will be asked to apply x-gate to randomly picked quantum bits.

Here is one of the methods to pick a random number in python.

from random import randrange
n =20
r=randrange(n)# pick a number from the list {0,1,...,n-1}
print(r)

# test this method by using a loop
for i inrange(10):
print(randrange(n))

### Task 2: Randomly picking an 8-bit binary number

Design a quantum circuit with 8 quantum bits and 8 classical bits.

For each quantum bit, flip a coin by python, and apply x-gate if the outcome is head.