Skip to content

Commit cf60aa6

Browse files
committed
Implement Deutsch-Jozsa Algorithm In Qiskit
Signed-off-by: Abhishek Jaisingh <abhi2254015@gmail.com>
1 parent 05f4089 commit cf60aa6

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed

quantum/deutsch_jozsa.py

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Implement Deutsch-Josza Algorithm in Qiskit.
4+
5+
References:
6+
- https://en.wikipedia.org/wiki/Deutsch-Jozsa_algorithm
7+
- https://qiskit.org/textbook/ch-states/atoms-computation.html#4.2-Remembering-how-to-add-
8+
""" # noqa
9+
10+
import numpy as np
11+
import qiskit as q
12+
13+
14+
def dj_oracle(case: str, n: int) -> q.QuantumCircuit:
15+
# We need to make a QuantumCircuit object to return
16+
# This circuit has n+1 qubits: the size of the input,
17+
# plus one output qubit
18+
oracle_qc = q.QuantumCircuit(n+1)
19+
20+
# First, let's deal with the case in which oracle is balanced
21+
if case == "balanced":
22+
# First generate a random number that tells us which CNOTs to
23+
# wrap in X-gates:
24+
b = np.random.randint(1,2**n)
25+
# Next, format 'b' as a binary string of length 'n', padded with zeros:
26+
b_str = format(b, '0'+str(n)+'b')
27+
# Next, we place the first X-gates. Each digit in our binary string
28+
# correspopnds to a qubit, if the digit is 0, we do nothing, if it's 1
29+
# we apply an X-gate to that qubit:
30+
for qubit in range(len(b_str)):
31+
if b_str[qubit] == '1':
32+
oracle_qc.x(qubit)
33+
# Do the controlled-NOT gates for each qubit, using the output qubit
34+
# as the target:
35+
for qubit in range(n):
36+
oracle_qc.cx(qubit, n)
37+
# Next, place the final X-gates
38+
for qubit in range(len(b_str)):
39+
if b_str[qubit] == '1':
40+
oracle_qc.x(qubit)
41+
42+
# Case in which oracle is constant
43+
if case == "constant":
44+
# First decide what the fixed output of the oracle will be
45+
# (either always 0 or always 1)
46+
output = np.random.randint(2)
47+
if output == 1:
48+
oracle_qc.x(n)
49+
50+
oracle_gate = oracle_qc.to_gate()
51+
oracle_gate.name = "Oracle" # To show when we display the circuit
52+
return oracle_gate
53+
54+
55+
def dj_algorithm(oracle: q.QuantumCircuit, n: int) -> q.QuantumCircuit:
56+
dj_circuit = q.QuantumCircuit(n+1, n)
57+
# Set up the output qubit:
58+
dj_circuit.x(n)
59+
dj_circuit.h(n)
60+
# And set up the input register:
61+
for qubit in range(n):
62+
dj_circuit.h(qubit)
63+
# Let's append the oracle gate to our circuit:
64+
dj_circuit.append(oracle, range(n+1))
65+
# Finally, perform the H-gates again and measure:
66+
for qubit in range(n):
67+
dj_circuit.h(qubit)
68+
69+
for i in range(n):
70+
dj_circuit.measure(i, i)
71+
72+
return dj_circuit
73+
74+
75+
def deutsch_jozsa(case: str, n: int) -> q.result.counts.Counts:
76+
"""
77+
>>> deutsch_jozsa("constant", 3)
78+
{'000': 1000}
79+
>>> deutsch_jozsa("balanced", 3)
80+
{'111': 1000}
81+
"""
82+
# Use Aer's qasm_simulator
83+
simulator = q.Aer.get_backend("qasm_simulator")
84+
85+
oracle_gate = dj_oracle(case, n)
86+
dj_circuit = dj_algorithm(oracle_gate, n)
87+
88+
# Execute the circuit on the qasm simulator
89+
job = q.execute(dj_circuit, simulator, shots=1000)
90+
91+
# Return the histogram data of the results of the experiment.
92+
return job.result().get_counts(dj_circuit)
93+
94+
95+
if __name__ == "__main__":
96+
counts = deutsch_jozsa("constant", 3)
97+
print(f"Deutsch Jozsa - Constant Oracle: {counts}")
98+
99+
counts = deutsch_jozsa("balanced", 3)
100+
print(f"Deutsch Jozsa - Balanced Oracle: {counts}")

0 commit comments

Comments
 (0)