Introduction to uantum Computing (IN2381) – W2023/2024 Tutorial 4 solution
Christian B. Mendl, Wang Yu, Keefe Huang
Tutorial 4 (Quantum circuit simulation)
In the lecture you learned about the tensor product of vector spaces to define multiple qubit spaces. Here we discuss
how to compute and work with quantum gates applied to these qubits.
Given two vector spaces V and W and two operators A and B acting respectively on them, we define A ⊗ B
implicitly via
(A ⊗ B)(|vi ⊗ |wi) = (A |vi) ⊗ (B |wi) for all |vi ∈ V and |wi ∈ W.
Using matrix notation, this leads to the Kronecker product of two matrices A ∈ Cm×n and B ∈ Cp×q :
a11 B a12 B · · · a1n B
a21 B a22 B · · · a2n B
mp×nq
A⊗B = . .. ∈ C ,
.. ..
.. . . .
am1 B am2 B · · · amn B
with aij the entries of A, and the terms aij B denoting p × q submatrices. The corresponding circuit diagram is
A
A⊗B =
B
Now consider the following quantum circuit:
|ψi |ψ 0 i
X
(a) What is the overall matrix representation of the first operation on |ψi?
(b) Assemble this matrix using Python/NumPy.
(c) If |ψi was a 20 qubit state, what would be the dimension of the gates acting on it? Is it possible to store a
dense matrix of such dimension on your laptop/PC? Discuss.
If a gate only acts non-trivially on a subset of the qubits, it can be implemented without
forming the overall matrix. Specifically for a single-qubit gate U acting on the i-th qubit
|ψi U
(counting from zero), we can first reshape the input state |ψi into a 2i × 2 × 2N −i−1
tensor and then apply U to the second dimension.
(d) Write a function that applies H to an arbitrary qubit of an input state |ψi using a “matrix-free” approach.
(e) Implement analogous functions for the X, Z and CNOT gates. Test your implementation via the above circuit
with a random input state.
Solution
(a) There is a Hadamard gate acting on the top qubit, and identities on the remaining three. Therefore the first
operation is
H ⊗ I2 ⊗ I2 ⊗ I2 = H ⊗ I8 ∈ C16×16 ,
with In denoting the n × n identity matrix.
(b) The NumPy function kron implements the Kronecker product:
1
import numpy as np
H = 1/np.sqrt(2) * np.array([[1, 1], [1,-1]])
H1 = np.kron(H, np.eye(8))
(c) It would be a 220 ×220 matrix. Since a double precision floating-point value uses 8 bytes of memory, a matrix of
this size would require 220 · 220 · 8 bytes = 243 bytes ≈ 8.8 × 1012 bytes = 8.8 TB of memory. No conventional
PC or laptop has that much RAM. For a general gate with complex entries, even twice as much memory is
needed.
(d) See Jupyter notebook.
(e) See Jupyter notebook.