Coding single qubit circuits in Qiskit

Madeline Farina
QubitCo
Published in
7 min readSep 17, 2020

Qiskit is an open-source framework developed by IBM for coding with quantum computing. It allows users to create quantum programs and run them on actual quantum computers via IBM’s cloud service, IBM Q Experience. Since the primary version of Qiskit uses the common programming language Python, it can be conveniently run in a Jupyter Notebook, which is what I will be using in the following tutorial.

If you’re unfamiliar with Qiskit or you are unsure how to use a Jupyter Notebook, refer to my last tutorial for a walkthrough of how to get it set up (I promise it’s quick and easy!). If you need an explanation of quantum concepts like the Bloch sphere and unary operators, check out my last post here, titled “A Prequel to Coding Quantum Circuits”.

Once you have a Jupyter Notebook open, you’re ready to start coding single qubit circuits and their visualizations. Remember, to run a line of code in a Jupyter Notebook, you must hit Shift + Enter to execute said code, so for every code block below, remember to do so.

Step 1. Install Qiskit

To install Qiskit, execute the following line of code within your Jupyter Notebook:

!pip install qiskit[visualization]

Once installation is complete with little to no error messages in the output, check your version (mine was 0.15.2):

import qiskit
qiskit.__version__

Next, import the necessary libraries to be able to create circuits and visualizations:

from qiskit import QuantumCircuit
from qiskit.quantum_info import Statevector
from qiskit.quantum_info import state_fidelity
from qiskit.visualization import plot_bloch_multivector
from qiskit.visualization import plot_state_qsphere
from qiskit.visualization import plot_state_city
from qiskit.visualization import plot_state_paulivec
from qiskit.visualization import plot_state_hinton
from qiskit import ClassicalRegister, QuantumRegister, execute
from qiskit import BasicAer

Step 2. Create the six basis states

Now that all the set-up work has been done, the next step is to create the different basis states of a qubit. Each line creates a new state vector labelled with whatever is found within the single quotes.

svZero  = Statevector.from_label('0') 
svOne = Statevector.from_label('1')
svPlus = Statevector.from_label('+')
svMinus = Statevector.from_label('-')
svRight = Statevector.from_label('r')
svLeft = Statevector.from_label('l')

The ‘svRight’ and ‘svLeft’ variables are equivalent to the |+i⟩ and |-i⟩ states, respectfully. If you wish to see a visualization of any of the basis states represented on the Bloch sphere, execute this command (changing the ‘svZero’ variable to the variable of whichever state you wish to see):

plot_bloch_multivector(svZero,title='Zero')

When you run the above line, you should see something like this:

As you can see, the |0⟩ is represented on the positive z-axis as it should be.

Step 3. Create the X Gate

The first gate we will create is the X gate for a single qubit circuit. The X gate is a bit flip operation that is equivalent to the NOT gate in classical circuits. To do so, use the following code, changing the ‘mxC’ variable to any variable you prefer.

mcX = QuantumCircuit(1) # creating a quantum circuit with only one qubit
mcX.x(0) # adding an X gate on our circuit
mcX.draw('mpl') # drawing the circuit

Note: anything following a # in Qiskit is a comment, meaning it is ignored by the compiler (and is therefore a create way to include little notes to yourself about your code). Your output should look like this:

Cute, isn’t it?

To have X act on state zero, use the .evolve function:

new_svZero = svZero.evolve(mcX)
new_svZero

When executed, the output should be like so:

The ‘j’ is actually what we would consider i, the variable indicating imaginary numbers. It is a ‘j’ in Qiskit because in quantum mechanics, i can be used for current within circuits. Notwithstanding, the ‘+0j’ means if the qubit were to be represented as a matrix, none of the elements would contain an i like it would in the matrix representation for a Y gate. If it were to be, for example, ‘+0.70710678j’, then it would be (1/√2)i in the matrix.

Run the plot_bloch_multivector command to see the change of the qubit on the Bloch Sphere:

plot_bloch_multivector(svZero,title='Zero')

You can also see the qubit on the Q-sphere with the below code, which is used to observe amplitude and phase information. It is ideal for multi-qubit representations, which becomes more relevant for multi-qubit circuits.

plot_state_qsphere(new_svZero)

And the output should be like so:

(ignore the error message, it’s unimportant)

You can apply the X gate to rest of the basis states with the .evolve() function and view the changes on the Bloch sphere and Q-sphere, changing the ‘svZero’ variable to svOne, svPlus, etc.

Step 4. Create the other Unary Operators

Now you can create the rest of the gates (Y, Z, H, etc.) and apply them to the single qubit and view it on the Bloch Sphere and Q-sphere with the above code. For educational purposes, I will create a new single-qubit circuit and apply all gates at once:

mcCrazyCircuit = QuantumCircuit(1) # creating a quantum circuit with only one qubit
mcCrazyCircuit.id(0) # adding an I gate on our circuit
mcCrazyCircuit.x(0) # adding an X gate on our circuit
mcCrazyCircuit.y(0) # adding a Y gate on our circuit
mcCrazyCircuit.z(0) # adding a Z gate on our circuit
mcCrazyCircuit.h(0) # adding an H gate on our circuit
mcCrazyCircuit.s(0) # adding an S gate on our circuit
mcCrazyCircuit.t(0) # adding a T gate on our circuit
mcCrazyCircuit.sdg(0) # adding an S-dagger gate on our circuit
mcCrazyCircuit.tdg(0) # adding an T-dagger gate on our circuit
mcCrazyCircuit.draw('mpl') # drawing the circuit

I did not mention the S-dagger and T-dagger gates in my last post because they are not as commonly used, but basically they are the inverses of their corresponding gates because the S and T gates are not their own inverses unlike the others. The S†-gate is an Rϕ-gate with 𝜙=−𝜋/2, and R†-gate is an Rϕ-gate with 𝜙=−𝜋/4.

I also didn’t mention the I gate because that’s the Identity gate and has no effect, so it’s trivial. Regardless, the output for the above code should appear like so:

Step 5. Making a Measurement

For the last step, I will provide the code for making measurements on a single qubit circuit.

q = QuantumRegister(1) # creates a Quantum register of 1 qubit
c = ClassicalRegister(1) # creates a classical register of 1 bit
qc = QuantumCircuit(q, c) # creates a quantum circuit
qc.measure(q, c)
qc.draw()

Output:

Next we will create a QASM simulator for the backend. QASM is a Quantum Assembly Language Simulator. In classical computers, Assembly is a low-level programming language that uses registers in memory. QASM is similar in that after declaring the classical bits and qubits and registers, it describes the operations (gates) on those qubits and the measurements needed to obtain the classical result by inspecting the qubits.

In this case we have a single qubit and a single classical bit. As a result of the measurement we will get one of the two states |0⟩ or |1⟩ with certain probabilities given by the (squares of) their amplitudes. In order to compute those probabilities, we must simulate many pseudo-experiments and accumulate sufficient statistics

backend = BasicAer.get_backend('qasm_simulator')
job = execute(qc, backend, shots=1024)
job.result().get_counts(qc)

Output:

Apply the Hadamard gate to the quantum circuit and perform the measurement.

qc.h(q) # applies H gate
qc.measure(q, c) # performs measurement
qc.draw()

Output:

And finally, to get information on the process of the QASM program:

job = execute(qc, backend, shots=1024)
job.result().get_counts(qc)

Output:

Conclusion

Thus concludes this quick (and hopefully straightforward) tutorial on making a single qubit circuit with different gates. My next post shall cover circuits with multiple qubits, as well as more measurements and operations. For any additional questions, the documentation for Qiskit can be found here here.

--

--

Madeline Farina
QubitCo

Quantum Physics, InfoSec, and general scientific nonsense