Source code for braket.experimental.algorithms.bells_inequality.bells_inequality

# 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 collections import Counter

import numpy as np

from braket.circuits import Circuit, Qubit, circuit
from braket.devices import Device
from braket.tasks import QuantumTask


[docs] def create_bell_inequality_circuits( qubit0: Qubit = 0, qubit1: Qubit = 1, angle_A: float = 0, angle_B: float = np.pi / 3, angle_C: float = 2 * np.pi / 3, ) -> list[Circuit]: """Create the three circuits for Bell's inequality. Default angles will give maximum violation of Bell's inequality. Args: qubit0 (Qubit): First qubit. qubit1 (Qubit): Second qubit. angle_A (float): Angle for the first measurement basis A. Defaults to 0. angle_B (float): Angle for the second measurement basis B. Defaults to np.pi/3. angle_C (float): Angle for the third measurement basis C. Defaults to 2*np.pi/3 to give maximum violation of Bell's inequality. Returns: List[Circuit]: Three circuits circAB, circAC, circBC. """ circAB = bell_singlet_rotated_basis(qubit0, qubit1, angle_A, angle_B) circAC = bell_singlet_rotated_basis(qubit0, qubit1, angle_A, angle_C) circBC = bell_singlet_rotated_basis(qubit0, qubit1, angle_B, angle_C) return [circAB, circAC, circBC]
[docs] def run_bell_inequality( circuits: list[Circuit], device: Device, shots: int = 1_000, ) -> list[QuantumTask]: """Submit three Bell circuits to a device. Args: circuits (List[Circuit]): Three Bell inequality circuits in order circAB, circAC, circBC. device (Device): Quantum device or simulator. shots (int): Number of shots. Defaults to 1_000. Returns: List[QuantumTask]: List of quantum tasks. """ tasks = [device.run(circ, shots=shots) for circ in circuits] return tasks
[docs] def get_bell_inequality_results( tasks: list[QuantumTask], verbose: bool = True ) -> tuple[list[Counter], float, float, float]: """Return Bell task results after post-processing. Args: tasks (List[QuantumTask]): List of quantum tasks. verbose (bool): Controls printing of the inequality result. Defaults to True. Returns: Tuple[List[Counter], float, float, float]: results, pAB, pAC, pBC """ results = [task.result().result_types[0].value for task in tasks] # probability result type prob_same = np.array([d[0] + d[3] for d in results]) # 00 and 11 states prob_different = np.array([d[1] + d[2] for d in results]) # 01 and 10 states pAB, pAC, pBC = prob_same - prob_different # Bell probabilities bell_ineqality_lhs = np.abs(pAB - pAC) - pBC if verbose: print(f"P(a,b) = {pAB},P(a,c) = {pAC},P(b,c) = {pBC}") print(f"Bell's' inequality: {bell_ineqality_lhs} ≤ 1") if bell_ineqality_lhs > 1: print("Bell's inequality is violated!") else: print("Bell's inequality is not violated due to noise.") return results, pAB, pAC, pBC
[docs] def bell_singlet_rotated_basis( qubit0: Qubit, qubit1: Qubit, rotation0: float, rotation1: float ) -> Circuit: """Prepare a Bell singlet state in a Rx-rotated meaurement basis. Args: qubit0 (Qubit): First qubit. qubit1 (Qubit): Second qubit. rotation0 (float): First qubit Rx rotation angle. rotation1 (float): Second qubit Rx rotation angle. Returns: Circuit: the Braket circuit that prepares the Bell circuit. """ circ = Circuit().bell_singlet(qubit0, qubit1) if rotation0 != 0: circ.rx(qubit0, rotation0) if rotation1 != 0: circ.rx(qubit1, rotation1) circ.probability() return circ
[docs] @circuit.subroutine(register=True) def bell_singlet(qubit0: Qubit, qubit1: Qubit) -> Circuit: """Prepare a Bell singlet state. Args: qubit0 (Qubit): First qubit. qubit1 (Qubit): Second qubit. Returns: Circuit: the Braket circuit that prepares the Bell single state. """ return Circuit().x(qubit0).x(qubit1).h(qubit0).cnot(qubit0, qubit1)