In the Introduction to Quantum Algorithms module, we sped up the lock-breaking process by testing states in pairs. This told us when the solution was present, but not which state it was. Our goal now will be to try and figure out the state directly, and our broad strategy will be to start in the uniform superposition and somehow "pump" amplitude from the other states into , so that we measure the solution with high probability. This strategy is called amplitude amplification. Let's start by exploring what happens to amplitudes when we apply the oracle.

Complete the following code for returning the amplitudes after applying the oracle to the uniform superposition. The oracle is accessible as oracle_matrix(combo), where combo is the secret combination. Amplitudes will be plotted for combo = [0, 0, 0, 1].

Hint. Since the oracle is encoded as a matrix, you will need to use the QubitUnitary() method in PennyLane.
n_bits = 4
dev = qml.device("default.qubit", wires=n_bits)


def oracle_matrix(combo):
"""Return the oracle matrix for a secret combination.

Args:
combo (list[int]): A list of bits representing a secret combination.

Returns:
array[float]: The matrix representation of the oracle.
"""
index = np.ravel_multi_index(combo, [2] * len(combo)) # Index of solution
my_array = np.identity(2 ** len(combo)) # Create the identity matrix
my_array[index, index] = -1
return my_array


@qml.qnode(dev)
def oracle_amp(combo):
"""Prepare the uniform superposition and apply the oracle.

Args:
combo (list[int]): A list of bits representing the secret combination.

Returns:
array[complex]: The quantum state (amplitudes) after applying the oracle.
"""
##################
# YOUR CODE HERE #
##################
return qml.state()

or to submit your code

To interact with codercises, please switch to a larger screen size.

Learning Objectives:

  • Describe the strategy of amplitude amplification.
  • Define the diffusion operator and visualize its effect on the uniform superposition.