COMS 4281 – Intro to Quantum Computing

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)