Deutsch's Algorithm

Get introduced to the concept of Deutsch's algorithm and its implementation.

Deutsch’s algorithm implementation

In our last example, we asked the oracle whether the function is constant or balanced. And this is what we get as an answer. Not more, not less.

The following code shows a function that embeds a discrete oracle in a quantum circuit.

This circuit includes a measurement of the first qubit. Therefore, our QuantumCircuit contains a QuantumRegister with two qubits (line 11) and a ClassicalRegister with one bit (line 12) to hold the measurement.

By default, both qubits are initialized in the state 0|0\rangle. We put the second qubit into the state 1|1\rangle by applying the X-gate in line 18. Then, we apply the Hadamard gate to both qubits in lines 20-21. We send the two qubits through the oracle in line 24 that we take as a parameter of this function in line 5.

We apply another Hadamard gate on the first qubit we received as an output of the oracle in line 27. We measure it and store it in the ClassicalRegister in line 30. We use the qasm_simulator in line 33 because it supports multiple executions (in this case, it supports up to 1,000 executions in line 36) of a quantum circuit that includes a measurement (see the lesson Hands-on introduction to quantum entanglement).

Even though our algorithm around the oracle treats it as a black box, we need a corresponding implementation when we want to run the oracle for a specific function.

Press + to interact
from math import sqrt
from qiskit import QuantumCircuit, QuantumRegister,ClassicalRegister, Aer, execute
from qiskit.visualization import plot_histogram
def solve(oracle):
"""
A reusable function that identifies whether the oracle represents
a constant or a balanced function.
"""
qu = QuantumRegister(2)
cl = ClassicalRegister(1)
# initialize the circuit
qc = QuantumCircuit(qu,cl)
# Prepare the input state of the oracle
qc.x(1)
qc.h(0)
qc.h(1)
# Apply the Oracle
oracle(qc)
# Prepare the output state
qc.h(0)
# measure qubit-0
qc.measure(qu[0], cl[0])
# Tell Qiskit how to simulate our circuit
backend = Aer.get_backend('qasm_simulator')
# execute the qc
results = execute(qc,backend, shots = 1000).result().get_counts()
# plot the results
#return plot_histogram(results)
return plot_histogram(results, figsize=(3,2), color=['white'])

Let’s implement the oracles. It’s a different one for each possible function fif_i.

We start with i=0i=0 and apply the function f0f_0 that always returns 0. As the truth table for the oracle O0O_0 from above shows, the output is the unchanged input

O0(xy)=xyf0(x)=xy0=xyO_0(|x\rangle\otimes|y\rangle)=|x\rangle\otimes|y\oplus|f_0(x)\rangle=|x\rangle\otimes|y\oplus|0\rangle=|x\rangle\otimes|y\rangle ...