9/13/22, 7:42 AM pset1
localhost:8888/nbconvert/html/pset1.ipynb?download=false 1/10
COMS 4281 – Intro to Quantum Computing
Problem Set 1, Quantum Info Basics
Due: September 23, 11�59pm
Collaboration is allowed and encouraged (teams of at most 3). Please read the syllabus
carefully for the guidlines regarding collaboration. In particular, everyone must write their
own solutions in their own words.
Please write your collaborators here:
Problem 1: Bra-Ket Notation Basics
�. Write out the state as linear combinations of the standard basis states . In
order for to be a valid quantum state (i.e. be a unit vector), what are the conditions
�. Since also forms a basis of (sometimes called the diagonal basis), write
as a linear combinations of and .
�. What is the probability of obtaining the and states when measuring ?
write your solution here, using LaTeX and Markdown
Problem 2: Outer Products and Projections
Recall that denotes a scalar, because is an inner product between two vectors (i.e.,
you have a row vector followed by a column vector). Now consider , which denotes
the outer product between the two vectors (i.e., a column vector followed by a row vector).
The outer product of two vectors is a matrix.
In [1]: %run utils.py
|ψ⟩ = α |0⟩ + β |+⟩
|ψ⟩ |0⟩ , |1⟩
{|+⟩ , |−⟩} C2
|ψ⟩ |+⟩ |−⟩
|0⟩ |1⟩ H |ψ⟩
9/13/22, 7:42 AM pset1
localhost:8888/nbconvert/html/pset1.ipynb?download=false 2/10
�. Show that and , where and
�. Let denote the standard basis for . Show that
. This simple identity known as the completeness relation can
be very useful.
�. Use the completeness relation to show that for any vector .
Thus the amplitudes of , in the standard basis, can be written as inner products of
with the standard basis vectors.
write your solution here, using LaTeX and Markdown
Problem 3: Composite Quantum Systems
Here are some questions to help you get used to the tensor product.
Let and . Recall that the tensor product can be given by:
is an dimensional matrix. This is also known as the Kronecker product which is a
way to represent the tensor product with respect to a given basis.
�. Give the explicit matrix representations for the matrices , and .
�. Compute , and , expressing the results in
the standard basis (i.e. and some constants )
write your solution here, using LaTeX and Markdown
Problem 4: Quantum Entanglement
|0⟩⟨0| = (I + Z)1
|+⟩⟨+| = (I + X)1
{|0⟩ , |1⟩ , … , |n − 1⟩} Cn
x=0 |x⟩⟨x|
⟨x|ψ⟩ |x⟩ |ψ⟩
A ∈ Rn×n B ∈ Rm×m A ⊗ B
A11B A12B ⋯ A1nB
A11B A12B ⋯ A2nB
An1B An2B ⋯ AnnB
I ⊗ H H ⊗ I H ⊗ H
(I ⊗ H) |0, 1⟩ (H ⊗ I) |0, 1⟩ (H ⊗ H) |0, 1⟩
i,j∈{0,1} cij |i⟩ |j⟩ cij ∈ C
9/13/22, 7:42 AM pset1
localhost:8888/nbconvert/html/pset1.ipynb?download=false 3/10
For each of the following quantum states, say whether they are entangled or unentangled
across the specified bipartition, and justify your answer.
�. is a two-qubit state in , called the
EPR pair . Are the two qubits entangled?
�. is an -qubit state where is a
basis state for . Let’s say we divide the qubits into the first and the last
qubits. Is the state entangled across the bipartition ?
�. Let be the EPR pair. Let denote the Hadamard gate. Is the
state entangled?
�. Is the state entangled?
write your solution here, using LaTeX and Markdown
Problem 5: Implement a Quantum Circuit
In this problem, you will implement a simple quantum circuit that constructs the
from the all zeroes state. In other words, you will find a circuit
In this problem, you will use the Qiskit library to implement, visualize, and analyze the circuit
�. Design a circuit to prepare the state , and write the corresponding Qiskit code
between the “BEGIN CODE” and “END CODE” delineations below. You may use any of
the gates we have learned in class. We’ve already created the circuit object, you just
need to specify what gates to add.
|Φ⟩ = ( |00⟩ + |11⟩) =
x∈{0,1}n |x⟩
n |x⟩ = |x1⟩ ⊗ |x2⟩ ⊗ ⋯ ⊗ |xn⟩
(C2)⊗n n j
n − j (C2)⊗j ⊗ (C2)⊗(n−j)
(I ⊗ H) |Φ⟩
|ψ⟩ = (|000⟩ − |111⟩)1
C |000⟩ = |ψ⟩
In [2]: def create_sym_state_circuit():
qr = QuantumRegister(3, name=’x’)
qc = QuantumCircuit(qr)
9/13/22, 7:42 AM pset1
localhost:8888/nbconvert/html/pset1.ipynb?download=false 4/10
�. Consult the qiskit documentation and use its API to obtain the output state of the circuit
you just created as a vector (i.e. a list of amplitudes).
It doesn’t matter for this problem, but keep in mind that qiskit uses the little-endian
convention (e.g., qubits are ordered right to left; for more info see this). We provide a
function beautify, which given input amplitude and k where amplitude is a list
of complex numbers and is an integer, prints the amplitude list as a quantum state.
See the code below as an example.
State vector: -1.55 |00> + (-1+0.1i) |01> – 1.1i |11>
In the following code block, print the output of the circuit you created in Part 1 above as a
vector in beautified form.
�. Write code to measure all the qubits of the state in the standard basis and visualize
the measurement statistics using a histogram.
# ========= BEGIN CODE =================
# ========= END CODE =================
qc = create_sym_state_circuit()
qc.draw(output=’mpl’)
In [16]: # Example for beautify
amplitudes = [complex(-1.55345, 0), complex(0,0), complex(-1, 0.1), comp
print(‘State vector:’, beautify(amplitudes, 2))
In [4]: # ========= BEGIN CODE =================
# ========= END CODE =================
In [5]: # ========= BEGIN CODE =================
https://quantumcomputing.stackexchange.com/questions/8244/big-endian-vs-little-endian-in-qiskit
9/13/22, 7:42 AM pset1
localhost:8888/nbconvert/html/pset1.ipynb?download=false 5/10
�. Consider running the following circuit with as input. Let denote the output state.
Calculate the state by computing the intermediate states of the circuit, and write it
out below in .
�. Write code to implement a circuit that prepares the state , measure it in the standard
basis and visualize the statistics using a histogram.
Problem 6: A Quantum Two-bit Adder
The classical two-bit adder is an irreversible function that takes in four bits, and
, and outputs three bits which is the binary representation of the sum
of and (i.e., integers that and represent in binary).
For example, on input and the two bit adder should return . On input
and it should output .
You can find a circuit for an irreversible circuit for the two-bit adder here, consisting of XOR,
OR, and AND gates (see Wikipedia for gate symbol reference).
In this problem you will implement a reversible two-bit adder in Qiskit.
�. First, let’s implement reversible versions of the XOR, OR, and AND gates. Recall that
every boolean function can be converted to a reversible transformation using an
additional ancilla bit. Since XOR, OR, AND map 2 bits to 1 bit, the reversible functions
will map 3 bits to 3 bits. The corresponding matrices are .
# ========= END CODE =================
In [6]: # ========= BEGIN CODE =================
# ========= END CODE =================
(B0, B1) (C0, Q0, Q1)
2A1 + A0 2B1 + B0 (A0, A1) (B0, B1)
(0, 1) (1, 1) (1, 0, 0)
(1, 1) (1, 1) (1, 1, 0)
TXOR, TOR, TAND 8 × 8
https://img.f-alpha.net/electronics/digital_electronics/adder/circuit_diagram_2_bit_adder.gif
https://en.wikipedia.org/wiki/Logic_gate
9/13/22, 7:42 AM pset1
localhost:8888/nbconvert/html/pset1.ipynb?download=false 6/10
In the functions below, enter the matrix representations of below
(replace the entries with the appropriate values). The row/columns are ordered as follows:
Your implementations of reversible XOR, OR, and AND will be tested.
TXOR, TOR, TAND
|000⟩ , |001⟩ , |010⟩ , … , |111⟩
In [7]: def create_Tor(qr: QuantumRegister) -> QuantumCircuit:
assert len(qr) == 3, ‘Tor gate should operate on 3 qubits.’
qc = QuantumCircuit(qr)
##### FILL IN THE MATRIX BELOW FOR THE REVERSIBLE OR GATE ##########
Tor = Operator([
[1, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 1],
####################################################################
qc.unitary(Tor, [2, 1, 0], label=’Tor’)
def create_Txor(qr: QuantumRegister) -> QuantumCircuit:
assert len(qr) == 3, ‘Txor gate should operate on 3 qubits.’
qc = QuantumCircuit(qr)
##### FILL IN THE MATRIX BELOW FOR THE REVERSIBLE XOR GATE ##########
Txor = Operator([
[1, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 1],
####################################################################
qc.unitary(Txor, [2, 1, 0], label=’Txor’)
def create_Tand(qr: QuantumRegister) -> QuantumCircuit:
assert len(qr) == 3, ‘Tand gate should operate on 3 qubits.’
qc = QuantumCircuit(qr)
##### FILL IN THE MATRIX BELOW FOR THE REVERSIBLE AND GATE ##########
Tand = Operator([
[1, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 1],
9/13/22, 7:42 AM pset1
localhost:8888/nbconvert/html/pset1.ipynb?download=false 7/10
Testing gates…
OR gate: Error.
XOR gate: Error.
AND gate: Error.
�. You can now put together reversible circuits consisting of , , and by
using the functions create_Tor , create_Txor , and create_Tand , and also a
helper function called append that allows you to append a gate to a circuit . The
function takes in a circuit , a function constructs the gate , and a list of bits that
operates on. See the code below as an example.
Now, transform the irreversible circuit for the two-bit adder above to a reversible circuit
for the two-bit adder. More precisely, the circuit should act on bits
representing the first number
representing the second number
representing the binary representation of
Some number of ancilla bits
The circuit should have the behavior: for all inputs ,
####################################################################
qc.unitary(Tand, [2, 1, 0], label=’Tand’)
In [8]: #Running test cases on your adder….
test_gates([create_Tor,create_Txor,create_Tand])
TXOR TOR TAND
In [9]: ### EXAMPLE ONLY ###############
qx = QuantumRegister(2, name=”x”)
qa = QuantumRegister(2, name=”a”)
qc = QuantumCircuit(qx,qa) #add the X register and A registers
qc = append(qc, create_Tand, [0, 1, 2]) #reversible AND acting on (x0,x1) and
qc = append(qc, create_Txor, [0,1,3]) #reversible XOR acting on (x0,x1) and
qc.draw(output=’mpl’)
(A0, A1) A = 2A1 + A0
(B0, B1) B = 2B1 + B0
(C0, C1, C2) A + B
(D0, D1, …)
C A0, A1, B0, B1 ∈ {0, 1}
C |A, B, 0, 0 ⋯ 0⟩ =
9/13/22, 7:42 AM pset1
localhost:8888/nbconvert/html/pset1.ipynb?download=false 8/10
where are two bits and is represented by three bits. corresponds to the
bits of the ancilla that depends on the inputs . This data corresponds to the “scratch
work” of the computation.
Your circuit can use , as well as , , and gates. Choose
the appropriate number of ancillas, and then implement your circuit where indicated. The
code afterwards will visualize your circuit as well run it on several test cases.
A, B A + B SA,B
C TXOR, TAND, TOR CNOT X Z H
In [10]: # Todo: fill in the number of ancillary qubits for your circuit
num_anc = 1
def create_two_bit_adder_with_scratch(num_anc):
A = QuantumRegister(2, name=”a”)
B = QuantumRegister(2, name=”b”)
C = QuantumRegister(3, name=”c”)
D = QuantumRegister(num_anc, name=”d”)
qc = QuantumCircuit(A,B,C,D)
#### BEGIN YOUR CODE HERE ############################
##### END YOUR CODE HERE ###############################
two_bit_adder_with_scratch = create_two_bit_adder_with_scratch(num_anc=num_anc)
two_bit_adder_with_scratch.draw(output=’mpl’)
In [11]: # Running test cases on your adder….
test_two_bit_adder(two_bit_adder_with_scratch, num_anc, has_scratch=True)
9/13/22, 7:42 AM pset1
localhost:8888/nbconvert/html/pset1.ipynb?download=false 9/10
Testing two-bit adder with scratch…
Error (incorrect): A = 00, B = 01, C = 000.
Error (incorrect): A = 00, B = 10, C = 000.
Error (incorrect): A = 00, B = 11, C = 000.
Error (incorrect): A = 01, B = 00, C = 000.
Error (incorrect): A = 01, B = 01, C = 000.
Error (incorrect): A = 01, B = 10, C = 000.
Error (incorrect): A = 01, B = 11, C = 000.
Error (incorrect): A = 10, B = 00, C = 000.
Error (incorrect): A = 10, B = 01, C = 000.
Error (incorrect): A = 10, B = 10, C = 000.
Error (incorrect): A = 10, B = 11, C = 000.
Error (incorrect): A = 11, B = 00, C = 000.
Error (incorrect): A = 11, B = 01, C = 000.
Error (incorrect): A = 11, B = 10, C = 000.
Error (incorrect): A = 11, B = 11, C = 000.
�. Now we go one step further to implement a reversible two-bit adder that does the same
thing as above except the scratch bits start and end in the zero state.
In other words, the scratch work is erased.
Hint: Use an additional ancilla to save the output, and then reverse the computation.
C |A, B, 0, 0 ⋯ 0⟩ = |A, B, A + B, 0 ⋯ 0⟩
In [12]: def create_two_bit_adder() -> QuantumCircuit:
A = QuantumRegister(2, name=”a”)
B = QuantumRegister(2, name=”b”)
C = QuantumRegister(3, name=”c”)
D = QuantumRegister(num_anc, name=”d”)
qc = QuantumCircuit(A,B,C,D)
#### BEGIN YOUR CODE HERE ############################
##### END YOUR CODE HERE ###############################
two_bit_adder = create_two_bit_adder()
two_bit_adder.draw(output=’mpl’)
9/13/22, 7:42 AM pset1
localhost:8888/nbconvert/html/pset1.ipynb?download=false 10/10
Testing two-bit adder without scratch…
Error (incorrect): A = 00, B = 01, C = 000.
Error (incorrect): A = 00, B = 10, C = 000.
Error (incorrect): A = 00, B = 11, C = 000.
Error (incorrect): A = 01, B = 00, C = 000.
Error (incorrect): A = 01, B = 01, C = 000.
Error (incorrect): A = 01, B = 10, C = 000.
Error (incorrect): A = 01, B = 11, C = 000.
Error (incorrect): A = 10, B = 00, C = 000.
Error (incorrect): A = 10, B = 01, C = 000.
Error (incorrect): A = 10, B = 10, C = 000.
Error (incorrect): A = 10, B = 11, C = 000.
Error (incorrect): A = 11, B = 00, C = 000.
Error (incorrect): A = 11, B = 01, C = 000.
Error (incorrect): A = 11, B = 10, C = 000.
Error (incorrect): A = 11, B = 11, C = 000.
In [13]: #Running test cases on your adder….
test_two_bit_adder(two_bit_adder, num_anc, has_scratch=False)