This post documents an interactive laboratory session focused on manipulating and visualizing single and multi-qubit quantum states using the Qiskit framework. The exercises cover fundamental concepts, including state initialization, quantum gates, superposition, entanglement, measurement, and the quantum teleportation algorithm.
Single-Qubit State Manipulation
Single-qubit states, represented generally as , where
denotes the probability of measuring the
state and
represents the relative phase.
A fundamental operation involves creating a quantum circuit. A single-qubit circuit without any gates was initialized as follows:
from qiskit import QuantumCircuit
mycircuit = QuantumCircuit(1)
mycircuit.draw('mpl')
This created a circuit with one qubit. To examine the state of this qubit, the state was initialized using Qiskit’s
Statevector
class:
from qiskit.quantum_info import Statevector
sv = Statevector.from_label('0')
print(f"Statevector object: {sv}")
print(f"Statevector data: {sv.data}")
The output confirmed the statevector representation of as:
Applying the empty circuit to this state resulted in no change, which was verified by evolving the statevector and calculating the state fidelity:
new_sv = sv.evolve(mycircuit)
print(f"Evolved statevector: {new_sv}")
from qiskit.quantum_info import state_fidelity
fidelity = state_fidelity(sv, new_sv)
print(f"State fidelity: {fidelity}")
A fidelity of 1 indicated that the initial and evolved states were identical. The qsphere
visualization provided a geometric representation of the quantum state:
from qiskit.visualization import plot_state_qsphere
plot_state_qsphere(sv.data)
The application of the gate, flips the qubit state from
to
:
mycircuit = QuantumCircuit(1)
mycircuit.x(0)
mycircuit.draw('mpl')
sv = Statevector.from_label('0')
new_sv = sv.evolve(mycircuit)
print(f"Evolved statevector after X gate: {new_sv}")
print(f"State fidelity with initial state: {state_fidelity(new_sv, sv)}")
plot_state_qsphere(new_sv.data)
The resulting statevector:
and the qsphere
visualization confirmed the X gate’s action, indicating orthogonality.
The Hadamard () gate, which creates superposition states. Applying it to
produced the state :
sv = Statevector.from_label('0')
mycircuit = QuantumCircuit(1)
mycircuit.h(0)
mycircuit.draw('mpl')
new_sv = sv.evolve(mycircuit)
print(f"Evolved statevector after H gate on |0>: {new_sv}")
plot_state_qsphere(new_sv.data)
Applying the Hadamard gate to resulted in the superposition state:
sv = Statevector.from_label('1')
mycircuit = QuantumCircuit(1)
mycircuit.h(0)
new_sv = sv.evolve(mycircuit)
print(f"Evolved statevector after H gate on |1>: {new_sv}")
plot_state_qsphere(new_sv.data)
The qsphere
visualization clearly showed the phase difference through color coding. The and
gates, which apply phase shifts of
anfd
, respectively, and provided an interactive widget for exploring the effects of various single-qubit gates.
Multi-Qubit State Exploration
The focus then shifted to multi-qubit states, particularly the generation of Bell states. The Bell state was created by applying a Hadamard gate to the first qubit of a two-qubit system initialized in the
state, followed by a controlled-NOT (CNOT) gate:
sv = Statevector.from_label('00')
plot_state_qsphere(sv.data)
mycircuit = QuantumCircuit(2)
mycircuit.h(0)
mycircuit.cx(0,1)
mycircuit.draw('mpl')
new_sv = sv.evolve(mycircuit)
print(f"Evolved statevector (Bell state): {new_sv}")
plot_state_qsphere(new_sv.data)
The qsphere
visualization illustrated the entangled nature of the Bell state. Simulating measurements of this state demonstrated the correlation between the two qubits:
counts = new_sv.sample_counts(shots=1000)
from qiskit.visualization import plot_histogram
plot_histogram(counts)
The histogram showed that measurements yielded either 00
or 11
with equal probability, highlighting the entanglement.
Quantum Measurement
The concept of explicit measurement within a quantum circuit was introduced. A circuit to create and measure the Bell state was constructed:
mycircuit = QuantumCircuit(2, 2)
mycircuit.h(0)
mycircuit.cx(0,1)
mycircuit.measure([0,1], [0,1])
mycircuit.draw('mpl')
This circuit included two qubits and two classical bits to store the measurement outcomes. The measure
operation associated each qubit with a corresponding classical bit. The circuit was then simulated using Qiskit’s Aer
simulator:
from qiskit import Aer, execute
simulator = Aer.get_backend('qasm_simulator')
result = execute(mycircuit, simulator, shots=10000).result()
counts = result.get_counts(mycircuit)
plot_histogram(counts)
The resulting histogram of measurement outcomes mirrored the results obtained by sampling the statevector.
Graded Exercise 1: Quantum Teleportation
Implementing the quantum teleportation algorithm to transfer the state from Alice’s qubit to Bob’s qubit. The algorithm was broken down into four key steps:
- Initialization: Creating the state to be teleported on Alice’s qubit (
q0
). - Entanglement: Creating an entangled pair (Bell state) between Alice’s auxiliary qubit (
q1
) and Bob’s qubit (q2
). - Bell Measurement: Performing a Bell measurement on Alice’s two qubits (
q0
andq1
). - Controlled Operations: Applying classically controlled X and Z gates on Bob’s qubit (
q2
) based on the measurement outcomes.
import numpy as np
from qiskit import QuantumCircuit
def initialize_qubit(given_circuit, qubit_index):
amplitude_0 = np.sqrt(0.70) amplitude_1 = np.sqrt(0.30)
given_circuit.initialize([amplitude_0, amplitude_1], qubit_index)
return given_circuit
def entangle_qubits(given_circuit, qubit_Alice, qubit_Bob):
given_circuit.h(qubit_Alice)
given_circuit.cx(qubit_Alice, qubit_Bob)
return given_circuit1
def bell_meas_Alice_qubits(given_circuit, qubit1_Alice, qubit2_Alice, clbit1_Alice, clbit2_Alice):
given_circuit.cx(qubit1_Alice, qubit2_Alice)
given_circuit.h(qubit1_Alice)
given_circuit.measure([qubit1_Alice, qubit2_Alice], [clbit1_Alice, clbit2_Alice])
return given_circuit
def controlled_ops_Bob_qubit(given_circuit, qubit_Bob, clbit1_Alice, clbit2_Alice):
given_circuit.z(qubit_Bob).c_if(clbit1_Alice, 1)
given_circuit.x(qubit_Bob).c_if(clbit2_Alice, 1)
return given_circuit
The complete teleportation circuit can then be assembled and visualized:
from qiskit import QuantumRegister, ClassicalRegister
all_qubits_Alice = QuantumRegister(2, name='alice_q')
all_qubits_Bob = QuantumRegister(1, name='bob_q')
creg1_Alice = ClassicalRegister(1, name='alice_c1')
creg2_Alice = ClassicalRegister(1, name='alice_c2')
mycircuit = QuantumCircuit(all_qubits_Alice, all_qubits_Bob, creg1_Alice, creg2_Alice, name='teleportation')
initialize_qubit(mycircuit, all_qubits_Alice[0])
mycircuit.barrier()
entangle_qubits(mycircuit, all_qubits_Alice[1], all_qubits_Bob[0])
mycircuit.barrier()
bell_meas_Alice_qubits(mycircuit, all_qubits_Alice[0], all_qubits_Alice[1], creg1_Alice, creg2_Alice)
mycircuit.barrier()
controlled_ops_Bob_qubit(mycircuit, all_qubits_Bob[0], creg1_Alice, creg2_Alice)
mycircuit.draw('mpl')
Conclusion
This post provided hands-on experience with Qiskit for manipulating and visualizing single and multi-qubit quantum states. The exercises covered essential quantum computing concepts, culminating in the implementation of the quantum teleportation algorithm. The use of the qsphere
visualization tool offered valuable intuitive insights into the nature of quantum states and the effects of quantum gates.