The Deutsch-Jozsa algorithm
Ang pahinang ito ay hindi pa naisalin. Nakikita mo ang orihinal na bersyon sa Ingles.
Deutsch's algorithm outperforms all classical algorithms for a query problem, but the advantage is quite modest: one query versus two. The Deutsch-Jozsa algorithm extends this advantage — and, in fact, it can be used to solve a couple of different query problems.
Here's a quantum circuit description of the Deutsch-Jozsa algorithm. An additional classical post-processing step, not shown in the figure, may also be required depending on the specific problem being solved.
Of course, we haven't actually discussed what problems this algorithm solves; this is done in the two sections that follow.
The Deutsch-Jozsa problem
We'll begin with the query problem the Deutsch-Jozsa algorithm was originally intended to solve, which is known as the Deutsch-Jozsa problem.
The input function for this problem takes the form for an arbitrary positive integer Like Deutsch's problem, the task is to output if is constant and if is balanced, which again means that the number of input strings on which the function takes the value is equal to the number of input strings on which the function takes the value .
Notice that, when is larger than there are functions of the form that are neither constant nor balanced. For example, the function defined as
falls into neither of these two categories. For the Deutsch-Jozsa problem, we simply don't worry about functions like this — they're considered to be "don't care" inputs. That is, for this problem we have a promise that is either constant or balanced.
The Deutsch-Jozsa algorithm, with its single query, solves this problem in the following sense: if every one of the measurement outcomes is then the function is constant; and otherwise, if at least one of the measurement outcomes is then the function is balanced. Another way to say this is that the circuit described above is followed by a classical post-processing step in which the OR of the measurement outcomes is computed to produce the output.
Algorithm analysis
To analyze the performance of the Deutsch-Jozsa algorithm for the Deutsch-Jozsa problem, it's helpful to begin by thinking about the action of a single layer of Hadamard gates. A Hadamard operation can be expressed as a matrix in the usual way,
but we can also express this operation in terms of its action on standard basis states:
These two equations can be combined into a single formula,
which is true for both choices of
Now suppose that instead of just a single qubit we have qubits, and a Hadamard operation is performed on each. The combined operation on the qubits is described by the tensor product ( times), which we write as for conciseness and clarity. Using the formula from above, followed by expanding and then simplifying, we can express the action of this combined operation on the standard basis states of qubits like this:
Here, by the way, we're writing binary strings of length as and following Qiskit's indexing convention.
This formula provides us with a useful tool for analyzing the quantum circuit above. After the first layer of Hadamard gates is performed, the state of the qubits (including the leftmost/bottom qubit, which is treated separately from the rest) is
When the operation is performed, this state is transformed into
through exactly the same phase kick-back phenomenon that we saw in the analysis of Deutsch's algorithm.
Then the second layer of Hadamard gates is performed, which (by the formula above) transforms this state into
This expression looks somewhat complicated, and not too much can be concluded about the probabilities to obtain different measurement outcomes without knowing more about the function
Fortunately, all we need to know is the probability that every one of the measurement outcomes is — because that's the probability that the algorithm determines that is constant. This probability has a simple formula.
In greater detail, if is constant, then either for every string in which case the value of the sum is or for every string in which case the value of the sum is Dividing by and taking the square of the absolute value yields
If, on the other hand, is balanced, then takes the value on half of the strings and the value on the other half, so the terms and terms in the sum cancel and we're left with the value
We conclude that the algorithm operates correctly provided that the promise is fulfilled.
Classical difficulty
The Deutsch-Jozsa algorithm works every time, always giving us the correct answer when the promise is met, and requires a single query. How does this compare with classical query algorithms for the Deutsch-Jozsa problem?
First, any deterministic classical algorithm that correctly solves the Deutsch-Jozsa problem must make exponentially many queries: queries are required in the worst case. The reasoning is that, if a deterministic algorithm queries on or fewer different strings, and obtains the same function value every time, then both answers are still possible. The function might be constant, or it might be balanced but through bad luck the queries all happen to return the same function value.
The second possibility might seem unlikely — but for deterministic algorithms there's no randomness or uncertainty, so they will fail systematically on certain functions. We therefore have a significant advantage of quantum over classical algorithms in this regard.
There is a catch, however, which is that probabilistic classical algorithms can solve the Deutsch-Jozsa problem with very high probability using just a few queries. In particular, if we simply choose a few different strings of length randomly, and query on those strings, it's unlikely that we'll get the same function value for all of them when is balanced.
To be specific, if we choose input strings uniformly at random, evaluate and answer if the function values are all the same, and if not, then we'll always be correct when is constant, and wrong in the case that is balanced with probability just If we take for instance, this algorithm will answer correctly with probability greater than %.
For this reason, we do still have a rather modest advantage of quantum over classical algorithms — but it is nevertheless a quantifiable advantage representing an improvement over Deutsch's algorithm.
Deutsch-Jozsa with Qiskit
from qiskit import QuantumCircuit
from qiskit_aer import AerSimulator
import numpy as np
To implement the Deutsch-Jozsa algorithm in Qiskit, we'll start by defining a function dj_query that generates a quantum circuit implementing a query gate, for a randomly selected function satisfying the promise for the Deutsch-Jozsa problem.
With a 50% chance, the function is constant, and with 50% change the function is balanced.
For each of those two possibilities, the function is selected uniformly from the functions of that type.
The argument is the number of input bits of the function.
def dj_query(num_qubits):
# Create a circuit implementing for a query gate for a random function
# satisfying the promise for the Deutsch-Jozsa problem.
qc = QuantumCircuit(num_qubits + 1)
if np.random.randint(0, 2):
# Flip output qubit with 50% chance
qc.x(num_qubits)
if np.random.randint(0, 2):
# return constant circuit with 50% chance
return qc
# Choose half the possible input strings
on_states = np.random.choice(
range(2**num_qubits), # numbers to sample from
2**num_qubits // 2, # number of samples
replace=False, # makes sure states are only sampled once
)
def add_cx(qc, bit_string):
for qubit, bit in enumerate(reversed(bit_string)):
if bit == "1":
qc.x(qubit)
return qc
for state in on_states:
qc.barrier() # Barriers are added to help visualize how the functions are created.
qc = add_cx(qc, f"{state:0b}")
qc.mcx(list(range(num_qubits)), num_qubits)
qc = add_cx(qc, f"{state:0b}")
qc.barrier()
return qc
We can show the quantum circuit implementation of the query gate using the draw method as usual.
display(dj_query(3).draw(output="mpl"))
Next we define a function that creates the Deutsch-Jozsa circuit, taking a quantum circuit implementation of a query gate as an argument.
def compile_circuit(function: QuantumCircuit):
# Compiles a circuit for use in the Deutsch-Jozsa algorithm.
n = function.num_qubits - 1
qc = QuantumCircuit(n + 1, n)
qc.x(n)
qc.h(range(n + 1))
qc.compose(function, inplace=True)
qc.h(range(n))
qc.measure(range(n), range(n))
return qc
Finally, a function that runs the Deutsch-Jozsa circuit once is defined.
def dj_algorithm(function: QuantumCircuit):
# Determine if a function is constant or balanced.
qc = compile_circuit(function)
result = AerSimulator().run(qc, shots=1, memory=True).result()
measurements = result.get_memory()
if "1" in measurements[0]:
return "balanced"
return "constant"
We can test our implementation by choosing a function randomly, displaying the quantum circuit implementation of a query gate for this function, and then running the Deutsch-Jozsa algorithm on that function.
f = dj_query(3)
display(f.draw("mpl"))
display(dj_algorithm(f))

'balanced'
The Bernstein-Vazirani problem
Next, we'll discuss a problem known as the Bernstein-Vazirani problem. It's also called the Fourier sampling problem, although there are more general formulations of this problem that also go by that name.
First, let's introduce some notation. For any two binary strings and of length we define
We'll refer to this operation as the binary dot product. An alternative way to define it is like so.