コード例 #1
0
def _apply_noise_on_observable_result_types(
        circuit: Circuit,
        readout_noise_instructions: List[NoiseModelInstruction]) -> Circuit:
    """Applies readout noise based on the observable result types in the circuit. Each applicable
    Noise will be applied only once to a target in the ObservableResultType.

    Args:
        circuit (Circuit): The circuit to apply the readout noise to.
        readout_noise_instructions (List[NoiseModelInstruction]): The list of readout noise
            to apply.

    Returns:
        Circuit: The passed in circuit, with the readout noise applied.
    """
    result_types = circuit.result_types
    noise_to_apply = defaultdict(set)
    for result_type in result_types:
        if isinstance(result_type, ObservableResultType):
            target_qubits = list(result_type.target)
            for item_index, item in enumerate(readout_noise_instructions):
                if item.criteria.result_type_matches(result_type):
                    for target_qubit in target_qubits:
                        noise_to_apply[target_qubit].add(item_index)
    for qubit in noise_to_apply:
        for noise_item_index in noise_to_apply[qubit]:
            item = readout_noise_instructions[noise_item_index]
            circuit.apply_readout_noise(item.noise, qubit)
    return circuit
コード例 #2
0
    def _apply_gate_noise(
        cls,
        circuit: Circuit,
        gate_noise_instructions: List[NoiseModelInstruction],
    ) -> Circuit:
        """
        Applies the gate noise to return a new circuit that's the `noisy` version of the given
        circuit.

        Args:
            circuit (Circuit): a circuit to apply `noise` to.
            gate_noise_instructions (List[NoiseModelInstruction]): a list of gate noise
                instructions to apply to the circuit.

        Returns:
            Circuit: A new circuit that's a `noisy` version of the passed in circuit. The targets
            set will be populated with the list of targets in the new circuit.
        """
        new_circuit = Circuit()
        for circuit_instruction in circuit.instructions:
            new_circuit.add_instruction(circuit_instruction)
            target_qubits = list(circuit_instruction.target)
            for item in gate_noise_instructions:
                if item.criteria.instruction_matches(circuit_instruction):
                    if item.noise.fixed_qubit_count() == len(target_qubits):
                        new_circuit.add_instruction(
                            Instruction(item.noise, target_qubits))
                    else:
                        for qubit in target_qubits:
                            new_circuit.add_instruction(
                                Instruction(item.noise, qubit))
        for result_type in circuit.result_types:
            new_circuit.add_result_type(result_type)
        return new_circuit
コード例 #3
0
def test_apply_noise_to_gates_2QubitNoise_2(
    circuit_3qubit, noise_2qubit, noise_1qubit, noise_1qubit_2
):
    circ = apply_noise_to_gates(
        circuit_3qubit,
        [noise_1qubit, noise_2qubit, noise_1qubit_2],
        target_gates=[Gate.CZ],
        target_qubits=QubitSet([1, 2]),
    )

    expected = (
        Circuit()
        .add_instruction(Instruction(Gate.X(), 0))
        .add_instruction(Instruction(Gate.Y(), 1))
        .add_instruction(Instruction(Gate.CNot(), [0, 1]))
        .add_instruction(Instruction(Gate.Z(), 2))
        .add_instruction(Instruction(Gate.CZ(), [2, 1]))
        .add_instruction(Instruction(noise_1qubit, 1))
        .add_instruction(Instruction(noise_1qubit, 2))
        .add_instruction(Instruction(noise_2qubit, [2, 1]))
        .add_instruction(Instruction(noise_1qubit_2, 1))
        .add_instruction(Instruction(noise_1qubit_2, 2))
        .add_instruction(Instruction(Gate.CNot(), [0, 2]))
        .add_instruction(Instruction(Gate.CZ(), [1, 2]))
        .add_instruction(Instruction(noise_1qubit, 1))
        .add_instruction(Instruction(noise_1qubit, 2))
        .add_instruction(Instruction(noise_2qubit, [1, 2]))
        .add_instruction(Instruction(noise_1qubit_2, 1))
        .add_instruction(Instruction(noise_1qubit_2, 2))
    )

    assert circ == expected
コード例 #4
0
def test_apply_multiple_noise_1QubitNoise_2(circuit_2qubit, noise_1qubit,
                                            noise_1qubit_2):
    circ = circuit_2qubit.apply_gate_noise(
        noise_1qubit,
        target_gates=[Gate.X],
    ).apply_gate_noise(
        noise_1qubit_2,
        target_qubits=[0],
    )

    expected = (Circuit().add_instruction(Instruction(
        Gate.X(),
        0)).add_instruction(Instruction(noise_1qubit_2, 0)).add_instruction(
            Instruction(noise_1qubit, 0)).add_instruction(
                Instruction(Gate.Y(), 1)).add_instruction(
                    Instruction(Gate.X(), 0)).add_instruction(
                        Instruction(noise_1qubit_2, 0)).add_instruction(
                            Instruction(noise_1qubit, 0)).add_instruction(
                                Instruction(Gate.X(), 1)).add_instruction(
                                    Instruction(
                                        noise_1qubit, 1)).add_instruction(
                                            Instruction(
                                                Gate.CNot(),
                                                [0, 1])).add_instruction(
                                                    Instruction(
                                                        noise_1qubit_2, 0)))

    assert circ == expected
コード例 #5
0
def test_apply_noise_to_moments_initialization_2QubitNoise_2(
    circuit_2qubit, noise_2qubit, noise_1qubit, noise_1qubit_2
):
    circ = apply_noise_to_moments(
        circuit_2qubit,
        [noise_1qubit, noise_2qubit, noise_1qubit_2],
        target_qubits=QubitSet([0, 1]),
        position="initialization",
    )

    expected = (
        Circuit()
        .add_instruction(Instruction(noise_1qubit, 0))
        .add_instruction(Instruction(noise_1qubit, 1))
        .add_instruction(Instruction(noise_2qubit, [0, 1]))
        .add_instruction(Instruction(noise_1qubit_2, 0))
        .add_instruction(Instruction(noise_1qubit_2, 1))
        .add_instruction(Instruction(Gate.X(), 0))
        .add_instruction(Instruction(Gate.Y(), 1))
        .add_instruction(Instruction(Gate.X(), 0))
        .add_instruction(Instruction(Gate.X(), 1))
        .add_instruction(Instruction(Gate.CNot(), [0, 1]))
    )

    assert circ == expected
コード例 #6
0
def _(
    circuit: Circuit,
    aws_session: AwsSession,
    create_task_kwargs: Dict[str, Any],
    device_parameters: Union[dict, BraketSchemaBase],
    device_arn: str,
    *args,
    **kwargs,
) -> AwsQuantumTask:
    validate_circuit_and_shots(circuit, create_task_kwargs["shots"])

    # TODO: Update this to use `deviceCapabilities` from Amazon Braket's GetDevice operation
    # in order to decide what parameters to build.
    paradigm_parameters = GateModelParameters(qubitCount=circuit.qubit_count)
    if "ionq" in device_arn:
        device_parameters = IonqDeviceParameters(
            paradigmParameters=paradigm_parameters)
    elif "rigetti" in device_arn:
        device_parameters = RigettiDeviceParameters(
            paradigmParameters=paradigm_parameters)
    else:  # default to use simulator
        device_parameters = GateModelSimulatorDeviceParameters(
            paradigmParameters=paradigm_parameters)

    create_task_kwargs.update({
        "action": circuit.to_ir().json(),
        "deviceParameters": device_parameters.json()
    })
    task_arn = aws_session.create_quantum_task(**create_task_kwargs)
    return AwsQuantumTask(task_arn, aws_session, *args, **kwargs)
コード例 #7
0
def apply_noise_to_moments(
    circuit: Circuit, noise: Iterable[Type[Noise]], target_qubits: QubitSet, position: str
) -> Circuit:
    """
    Apply initialization/readout noise to the circuit.

    When `noise.qubit_count` == 1, `noise` is added to all qubits in `target_qubits`.

    When `noise.qubit_count` > 1, `noise.qubit_count` must be the same as the length of
    `target_qubits`.

    Args:
        circuit (Circuit): A ciruit where `noise` is applied to.
        noise (Iterable[Type[Noise]]): Noise channel(s) to be applied
            to the circuit.
        target_qubits (QubitSet): Index or indices of qubits. `noise` is applied to.

    Returns:
        Circuit: modified circuit.
    """
    noise_instructions = []
    for noise_channel in noise:
        if noise_channel.qubit_count == 1:
            new = [Instruction(noise_channel, qubit) for qubit in target_qubits]
            noise_instructions = noise_instructions + new
        else:
            noise_instructions.append(Instruction(noise_channel, target_qubits))

    new_moments = Moments()

    if position == "initialization":
        for noise in noise_instructions:
            new_moments.add_noise(noise, "initialization_noise")

    # add existing instructions
    for moment_key in circuit.moments:
        instruction = circuit.moments[moment_key]
        # if the instruction is noise instruction
        if isinstance(instruction.operator, Noise):
            new_moments.add_noise(instruction, moment_key.moment_type, moment_key.noise_index)
        # if the instruction is a gate instruction
        else:
            new_moments.add([instruction], moment_key.noise_index)

    if position == "readout":
        for noise in noise_instructions:
            new_moments.add_noise(noise, "readout_noise")

    circuit._moments = new_moments

    return circuit
コード例 #8
0
    def _apply_init_noise(
        cls,
        circuit: Circuit,
        init_noise_instructions: List[NoiseModelInstruction],
    ) -> Circuit:
        """
        Applies the initialization noise of this noise model to a circuit and returns the circuit.

        Args:
            circuit (Circuit): A circuit to apply `noise` to.
            init_noise_instructions (List[NoiseModelInstruction]): A list of initialization noise
                model instructions.

        Returns:
            Circuit: The passed in circuit, with the initialization noise applied.
        """
        if not init_noise_instructions:
            return circuit
        for item in init_noise_instructions:
            qubits = item.criteria.qubit_intersection(circuit.qubits)
            if len(qubits) > 0:
                circuit.apply_initialization_noise(item.noise, list(qubits))
        return circuit
コード例 #9
0
def _(
    circuit: Circuit,
    aws_session: AwsSession,
    create_task_kwargs: Dict[str, Any],
    device_arn: str,
    device_parameters: Union[
        dict, BraketSchemaBase],  # Not currently used for circuits
    disable_qubit_rewiring: bool,
    *args,
    **kwargs,
) -> AwsQuantumTask:
    validate_circuit_and_shots(circuit, create_task_kwargs["shots"])
    # TODO: Update this to use `deviceCapabilities` from Amazon Braket's GetDevice operation
    # in order to decide what parameters to build.
    paradigm_parameters = GateModelParameters(
        qubitCount=circuit.qubit_count,
        disableQubitRewiring=disable_qubit_rewiring)
    if "ionq" in device_arn:
        device_parameters = IonqDeviceParameters(
            paradigmParameters=paradigm_parameters)
    elif "rigetti" in device_arn:
        device_parameters = RigettiDeviceParameters(
            paradigmParameters=paradigm_parameters)
    elif "oqc" in device_arn:
        device_parameters = OqcDeviceParameters(
            paradigmParameters=paradigm_parameters)
    else:  # default to use simulator
        device_parameters = GateModelSimulatorDeviceParameters(
            paradigmParameters=paradigm_parameters)

    qubit_reference_type = QubitReferenceType.VIRTUAL

    if disable_qubit_rewiring or Instruction(
            StartVerbatimBox()) in circuit.instructions:
        qubit_reference_type = QubitReferenceType.PHYSICAL

    serialization_properties = OpenQASMSerializationProperties(
        qubit_reference_type=qubit_reference_type)

    create_task_kwargs.update({
        "action":
        circuit.to_ir(
            ir_type=IRType.OPENQASM,
            serialization_properties=serialization_properties,
        ).json(),
        "deviceParameters":
        device_parameters.json(),
    })
    task_arn = aws_session.create_quantum_task(**create_task_kwargs)
    return AwsQuantumTask(task_arn, aws_session, *args, **kwargs)
コード例 #10
0
def test_noise_not_applied_1QubitNoise_1(circuit_2qubit, noise_2qubit):
    circ = circuit_2qubit.apply_gate_noise(
        [noise_2qubit],
        target_qubits=[1],
        target_gates=[],
    )

    expected = (Circuit().add_instruction(Instruction(
        Gate.X(),
        0)).add_instruction(Instruction(Gate.Y(), 1)).add_instruction(
            Instruction(Gate.X(), 0)).add_instruction(Instruction(
                Gate.X(), 1)).add_instruction(Instruction(Gate.CNot(),
                                                          [0, 1])))

    assert circ == expected
コード例 #11
0
def test_apply_initialization_noise_1QubitNoise_1(circuit_2qubit,
                                                  noise_1qubit):
    circ = circuit_2qubit.apply_initialization_noise(
        [noise_1qubit],
        target_qubits=[0, 1],
    )

    expected = (Circuit().add_instruction(Instruction(
        noise_1qubit,
        0)).add_instruction(Instruction(noise_1qubit, 1)).add_instruction(
            Instruction(Gate.X(), 0)).add_instruction(Instruction(
                Gate.Y(),
                1)).add_instruction(Instruction(Gate.X(), 0)).add_instruction(
                    Instruction(Gate.X(), 1)).add_instruction(
                        Instruction(Gate.CNot(), [0, 1])))

    assert circ == expected
コード例 #12
0
def test_apply_gate_noise_2QubitNoise2_parametrized(
        circuit_2qubit_parametrized, noise_2qubit):
    circ = circuit_2qubit_parametrized.apply_gate_noise(
        noise_2qubit,
        target_gates=[Gate.XY],
        target_qubits=[0, 1],
    )

    expected = (Circuit().add_instruction(Instruction(
        Gate.X(),
        0)).add_instruction(Instruction(Gate.Y(), 1)).add_instruction(
            Instruction(Gate.X(), 0)).add_instruction(
                Instruction(Gate.Rx(np.pi), 1)).add_instruction(
                    Instruction(Gate.XY(np.pi / 2), [0, 1])).add_instruction(
                        Instruction(noise_2qubit, [0, 1])))

    assert circ == expected
コード例 #13
0
def test_apply_noise_to_moments_readout_1QubitNoise_2(circuit_2qubit,
                                                      noise_1qubit):
    circ = apply_noise_to_moments(
        circuit_2qubit,
        [noise_1qubit],
        target_qubits=QubitSet(1),
        position="readout",
    )

    expected = (Circuit().add_instruction(Instruction(
        Gate.X(),
        0)).add_instruction(Instruction(Gate.Y(), 1)).add_instruction(
            Instruction(Gate.X(), 0)).add_instruction(Instruction(
                Gate.X(), 1)).add_instruction(Instruction(
                    Gate.CNot(),
                    [0, 1])).add_instruction(Instruction(noise_1qubit, 1)))

    assert circ == expected
コード例 #14
0
def test_apply_noise_to_gates_1QubitNoise_2(circuit_2qubit, noise_1qubit):
    circ = apply_noise_to_gates(
        circuit_2qubit,
        [noise_1qubit],
        target_gates=[Gate.X],
        target_qubits=QubitSet(0),
    )

    expected = (Circuit().add_instruction(Instruction(
        Gate.X(),
        0)).add_instruction(Instruction(noise_1qubit, 0)).add_instruction(
            Instruction(Gate.Y(), 1)).add_instruction(Instruction(
                Gate.X(), 0)).add_instruction(Instruction(
                    noise_1qubit, 0)).add_instruction(Instruction(
                        Gate.X(),
                        1)).add_instruction(Instruction(Gate.CNot(), [0, 1])))

    assert circ == expected
コード例 #15
0
def test_apply_gate_noise_1QubitNoise_1_unitary(circuit_2qubit_with_unitary, noise_1qubit):
    circ = circuit_2qubit_with_unitary.apply_gate_noise(
        noise_1qubit,
        target_unitary=np.array([[0, 1], [1, 0]]),
        target_qubits=[0, 1],
    )

    expected = (
        Circuit()
        .add_instruction(Instruction(Gate.X(), 0))
        .add_instruction(Instruction(Gate.Y(), 1))
        .add_instruction(Instruction(Gate.X(), 0))
        .add_instruction(Instruction(Gate.X(), 1))
        .add_instruction(Instruction(Gate.CNot(), [0, 1]))
        .add_instruction(Instruction(Gate.Unitary(np.array([[0, 1], [1, 0]]), "U"), 0))
        .add_instruction(Instruction(noise_1qubit, 0))
    )

    assert circ == expected
コード例 #16
0
def _(
    circuit: Circuit,
    aws_session: AwsSession,
    create_task_kwargs: Dict[str, Any],
    device_arn: str,
    device_parameters: Union[
        dict, BraketSchemaBase],  # Not currently used for circuits
    disable_qubit_rewiring,
    *args,
    **kwargs,
) -> AwsQuantumTask:
    validate_circuit_and_shots(circuit, create_task_kwargs["shots"])
    if circuit.qubits_frozen and not disable_qubit_rewiring:
        raise ValueError(
            "disable_qubit_rewiring must be True to run circuit with compiler directives"
        )

    # TODO: Update this to use `deviceCapabilities` from Amazon Braket's GetDevice operation
    # in order to decide what parameters to build.
    paradigm_parameters = GateModelParameters(
        qubitCount=circuit.qubit_count,
        disableQubitRewiring=disable_qubit_rewiring)
    if "ionq" in device_arn:
        device_parameters = IonqDeviceParameters(
            paradigmParameters=paradigm_parameters)
    elif "rigetti" in device_arn:
        device_parameters = RigettiDeviceParameters(
            paradigmParameters=paradigm_parameters)
    else:  # default to use simulator
        device_parameters = GateModelSimulatorDeviceParameters(
            paradigmParameters=paradigm_parameters)

    create_task_kwargs.update({
        "action": circuit.to_ir().json(),
        "deviceParameters": device_parameters.json()
    })
    task_arn = aws_session.create_quantum_task(**create_task_kwargs)
    return AwsQuantumTask(task_arn, aws_session, *args, **kwargs)
コード例 #17
0
 def _generate_eigenstate_circuit(self, signs: Tuple[int, ...]) -> Circuit:
     circ = Circuit()
     for qubit in range(len(signs)):
         state = signs[qubit] * self[qubit]
         if state == -3:
             circ.x(qubit)
         elif state == 1:
             circ.h(qubit)
         elif state == -1:
             circ.x(qubit).h(qubit)
         elif state == 2:
             circ.h(qubit).s(qubit)
         elif state == -2:
             circ.h(qubit).si(qubit)
     return circ
コード例 #18
0
def circuit_2qubit_with_unitary():
    return Circuit().x(0).y(1).x(0).x(1).cnot(0, 1).unitary([0], matrix=np.array([[0, 1], [1, 0]]))
コード例 #19
0
def apply_noise_to_gates(
    circuit: Circuit,
    noise: Iterable[Type[Noise]],
    target_gates: Union[Iterable[Type[Gate]], np.ndarray],
    target_qubits: QubitSet,
) -> Circuit:
    """Apply noise after target gates in target qubits.

    When `noise.qubit_count` == 1, `noise` is applied to target_qubits after `target_gates`.

    When `noise.qubit_count` > 1, all elements in `target_gates`, if is given, must have
    the same number of qubits as `noise.qubit_count`.

    Args:
        circuit (Circuit): A ciruit where `noise` is applied to.
        noise (Iterable[Type[Noise]]): Noise channel(s) to be applied
            to the circuit.
        target_gates (Union[Iterable[Type[Gate]], np.ndarray]): List of gates, or a unitary matrix
            which `noise` is applied to.
        target_qubits (QubitSet): Index or indices of qubits which `noise` is applied to.

    Returns:
        Circuit: modified circuit.

    Raises:
        Warning:
            If `noise` is multi-qubit noise while there is no gate with the same
            number of qubits in `target_qubits` or in the whole circuit when
            `target_qubits` is not given.
            If no `target_gates` exist in `target_qubits` or in the whole circuit
            when `target_qubits` is not given.
    """

    new_moments = Moments()
    noise_applied = False

    for moment_key in circuit.moments:
        instruction = circuit.moments[moment_key]

        # add the instruction to new_moments if it is noise instruction
        if isinstance(instruction.operator, Noise):
            new_moments.add_noise(instruction, moment_key.moment_type, moment_key.noise_index)

        # if the instruction is a gate instruction
        else:
            new_noise_instruction = []
            noise_index = moment_key.noise_index
            if isinstance(target_gates, np.ndarray):
                if (instruction.operator.name == "Unitary") and (
                    np.array_equiv(instruction.operator._matrix, target_gates)
                ):
                    intersection = list(set(instruction.target) & set(target_qubits))
                    (
                        new_noise_instruction,
                        noise_index,
                        noise_applied,
                    ) = _apply_noise_to_gates_helper(
                        noise,
                        target_qubits,
                        instruction,
                        noise_index,
                        intersection,
                        noise_applied,
                        new_noise_instruction,
                    )

            elif (target_gates is None) or (
                instruction.operator.name in [g.__name__ for g in target_gates]
            ):
                intersection = list(set(instruction.target) & set(target_qubits))
                new_noise_instruction, noise_index, noise_applied = _apply_noise_to_gates_helper(
                    noise,
                    target_qubits,
                    instruction,
                    noise_index,
                    intersection,
                    noise_applied,
                    new_noise_instruction,
                )

            # add the gate and gate noise instructions to new_moments
            new_moments.add([instruction], noise_index=noise_index)
            for instruction, noise_index in new_noise_instruction:
                new_moments.add_noise(instruction, "gate_noise", noise_index)

    no_noise_applied_warning(noise_applied)
    circuit._moments = new_moments
    return circuit
コード例 #20
0
def circuit_2qubit_parametrized():
    return Circuit().x(0).y(1).x(0).rx(1, np.pi).xy(0, 1, np.pi / 2)
コード例 #21
0
def test_apply_readout_noise_mismatch_qubit_count_with_target_qubits(noise_2qubit):
    circ = Circuit().cswap(0, 1, 2)
    circ.apply_readout_noise(noise_2qubit, target_qubits=[0, 1, 2])
コード例 #22
0
def test_apply_gate_noise_mismatch_qubit_count_with_target_gates(noise_2qubit):
    circ = Circuit().cswap(0, 1, 2)
    circ.apply_gate_noise(noise_2qubit, target_gates=Gate.CSwap)
コード例 #23
0
def test_apply_gate_noise_fixed_qubit_count_not_implemented(noise_2qubit):
    circ = Circuit().unitary([0, 1], matrix=np.eye(4))
    circ.apply_gate_noise(noise_2qubit, target_gates=Gate.Unitary)
コード例 #24
0
def circuit_2qubit():
    return Circuit().x(0).y(1).x(0).x(1).cnot(0, 1)
コード例 #25
0
def test_apply_readout_noise_to_empty_circuit(noise_1qubit):
    Circuit().apply_readout_noise(noise_1qubit)
コード例 #26
0
def test_apply_initialization_noise_to_empty_circuit(noise_1qubit):
    Circuit().apply_initialization_noise(noise_1qubit)
コード例 #27
0
def test_apply_gate_noise_to_empty_circuit(noise_1qubit):
    Circuit().apply_gate_noise(noise_1qubit)
コード例 #28
0
def circuit_3qubit():
    return Circuit().x(0).y(1).cnot(0, 1).z(2).cz(2, 1).cnot(0, 2).cz(1, 2)
コード例 #29
0
def circuit_2qubit_not_dense():
    # there are some qubits and some time that are not occupied by a gate
    return Circuit().x(0).y(1).x(0).cnot(0, 1)