# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You
# may not use this file except in compliance with the License. A copy of
# the License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file is
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
from typing import Dict
import numpy as np
from braket.circuits import Circuit
from braket.devices import Device
from braket.tasks import QuantumTask
[docs]
def bernstein_vazirani_circuit(hidden_string: str) -> Circuit:
"""Bernstein–Vazirani circuit on a hidden string. Creates a circuit that finds the hidden
string in a single iteration, using number of qubits equal to the string length.
Example:
>>> circ = bernstein_vazirani_circuit("011")
>>> print(circ)
T : |0|1| 2 |3|4|Result Types|
q0 : -H---C---H---Probability--
| |
q1 : -H---|---C-H-Probability--
| | |
q2 : -H-I-|-H-|---Probability--
| |
q3 : -H-Z-X---X----------------
T : |0|1| 2 |3|4|Result Types|
Args:
hidden_string (str): Hidden bitstring.
Returns:
Circuit: Bernstein–Vazirani circuit
"""
num_qubits = len(hidden_string)
bv_circuit = Circuit()
bv_circuit.h(num_qubits)
bv_circuit.z(num_qubits)
bv_circuit.h(range(num_qubits))
for q in range(num_qubits):
if hidden_string[q] == "0":
bv_circuit.i(q)
else:
bv_circuit.cnot(q, num_qubits)
bv_circuit.h(range(num_qubits))
bv_circuit.probability(range(num_qubits))
return bv_circuit
[docs]
def get_bernstein_vazirani_results(task: QuantumTask) -> Dict[str, float]:
"""Return the probabilities and corresponding bitstrings.
Args:
task (QuantumTask): Quantum task to process.
Returns:
Dict[str, float]: Results as a dictionary of bitstrings
"""
probabilities = task.result().result_types[0].value
probabilities = np.round(probabilities, 10) # round off floating-point errors
num_qubits = int(np.log2(len(probabilities)))
binary_strings = [format(i, "b").zfill(num_qubits) for i in range(2**num_qubits)]
return dict(zip(binary_strings, probabilities))
[docs]
def run_bernstein_vazirani(
circuit: Circuit,
device: Device,
shots: int = 1000,
) -> QuantumTask:
"""Function to run Bernstein Vazirani algorithm on a device.
Args:
circuit (Circuit): Bernstein Vazirani circuit
device (Device): Braket device backend
shots (int) : Number of measurement shots (default is 1000).
Returns:
QuantumTask: Task from running Quantum Phase Estimation
"""
return device.run(circuit, shots=shots)