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
Beispiel #2
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
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
Beispiel #4
0
    def __init__(self, matrix: np.ndarray, display_name: str = "Hermitian"):
        """
        Args:
            matrix (numpy.ndarray): Hermitian matrix that defines the observable.
            display_name (str): Name to use for an instance of this Hermitian matrix
                observable for circuit diagrams. Defaults to `Hermitian`.

        Raises:
            ValueError: If `matrix` is not a two-dimensional square matrix,
                or has a dimension length that is not a positive power of 2,
                or is not Hermitian.

        Examples:
            >>> Observable.Hermitian(matrix=np.array([[0, 1],[1, 0]]))
        """
        verify_quantum_operator_matrix_dimensions(matrix)
        self._matrix = np.array(matrix, dtype=complex)
        if not is_hermitian(self._matrix):
            raise ValueError(f"{self._matrix} is not hermitian")

        qubit_count = int(np.log2(self._matrix.shape[0]))
        eigendecomposition = Hermitian._get_eigendecomposition(self._matrix)
        self._eigenvalues = eigendecomposition["eigenvalues"]
        self._diagonalizing_gates = (Gate.Unitary(
            matrix=eigendecomposition["eigenvectors"].conj().T), )

        super().__init__(qubit_count=qubit_count,
                         ascii_symbols=[display_name] * qubit_count)
Beispiel #5
0
    def unitary(targets: QubitSet, matrix: np.ndarray, display_name: str = "U") -> Instruction:
        """Registers this function into the circuit class.

        Args:
            targets (QubitSet): Target qubits.
            matrix (numpy.ndarray): Unitary matrix which defines the gate. Matrix should be
                compatible with the supplied targets, with `2 ** len(targets) == matrix.shape[0]`.
            display_name (str): Name to be used for an instance of this unitary gate
                for circuit diagrams. Defaults to `U`.

        Returns:
            Instruction: Unitary instruction.

        Raises:
            ValueError: If `matrix` is not a two-dimensional square matrix,
                or has a dimension length that is not compatible with the `targets`,
                or is not unitary,

        Examples:
            >>> circ = Circuit().unitary(matrix=np.array([[0, 1],[1, 0]]), targets=[0])
        """
        if 2 ** len(targets) != matrix.shape[0]:
            raise ValueError("Dimensions of the supplied unitary are incompatible with the targets")

        return Instruction(Gate.Unitary(matrix, display_name), target=targets)
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
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
Beispiel #8
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
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
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
Beispiel #11
0
def test_apply_noise_to_gates_1QubitNoise_not_dense(circuit_2qubit_not_dense, noise_1qubit):
    circ = apply_noise_to_gates(
        circuit_2qubit_not_dense,
        [noise_1qubit],
        target_qubits=QubitSet([0, 1]),
        target_gates=None,
    )

    expected_moments = Moments()
    expected_moments._add(Instruction(Gate.X(), 0), noise_index=1)
    expected_moments.add_noise(Instruction(noise_1qubit, 0), "gate_noise", 1)
    expected_moments._add(Instruction(Gate.Y(), 1), noise_index=1)
    expected_moments.add_noise(Instruction(noise_1qubit, 1), "gate_noise", 1)
    expected_moments._add(Instruction(Gate.X(), 0), noise_index=1)
    expected_moments.add_noise(Instruction(noise_1qubit, 0), "gate_noise", 1)
    expected_moments._add(Instruction(Gate.CNot(), [0, 1]), noise_index=2)
    expected_moments.add_noise(Instruction(noise_1qubit, 0), "gate_noise", 1)
    expected_moments.add_noise(Instruction(noise_1qubit, 1), "gate_noise", 2)

    assert circ.moments == expected_moments
Beispiel #12
0
    def i(target: QubitSetInput) -> Iterable[Instruction]:
        """Registers this function into the circuit class.

        Args:
            target (Qubit, int, or iterable of Qubit / int): Target qubit(s)

        Returns:
            Iterable[Instruction]: `Iterable` of I instructions.

        Examples:
            >>> circ = Circuit().i(0)
            >>> circ = Circuit().i([0, 1, 2])
        """
        return [Instruction(Gate.I(), target=qubit) for qubit in QubitSet(target)]
Beispiel #13
0
    def xy(target1: QubitInput, target2: QubitInput, angle: float) -> Instruction:
        """Registers this function into the circuit class.

        Args:
            target1 (Qubit or int): Target qubit 1 index.
            target2 (Qubit or int): Target qubit 2 index.

        Returns:
            Instruction: XY instruction.

        Examples:
            >>> circ = Circuit().xy(0, 1, 0.15)
        """
        return Instruction(Gate.XY(angle), target=[target1, target2])
Beispiel #14
0
    def iswap(target1: QubitInput, target2: QubitInput) -> Instruction:
        """Registers this function into the circuit class.

        Args:
            target1 (Qubit or int): Target qubit 1 index.
            target2 (Qubit or int): Target qubit 2 index.

        Returns:
            Instruction: ISwap instruction.

        Examples:
            >>> circ = Circuit().iswap(0, 1)
        """
        return Instruction(Gate.ISwap(), target=[target1, target2])
Beispiel #15
0
    def phaseshift(target: QubitInput, angle: float) -> Instruction:
        """Registers this function into the circuit class.

        Args:
            target (Qubit or int): Target qubit index.
            angle (float): Angle in radians.

        Returns:
            Instruction: PhaseShift instruction.

        Examples:
            >>> circ = Circuit().phaseshift(0, 0.15)
        """
        return [Instruction(Gate.PhaseShift(angle), target=qubit) for qubit in QubitSet(target)]
Beispiel #16
0
    def cy(control: QubitInput, target: QubitInput) -> Instruction:
        """Registers this function into the circuit class.

        Args:
            control (Qubit or int): Control qubit index.
            target (Qubit or int): Target qubit index.

        Returns:
            Instruction: CY instruction.

        Examples:
            >>> circ = Circuit().cy(0, 1)
        """
        return Instruction(Gate.CY(), target=[control, target])
Beispiel #17
0
    def ccnot(control1: QubitInput, control2: QubitInput, target: QubitInput) -> Instruction:
        """Registers this function into the circuit class.

        Args:
            control1 (Qubit or int): Control qubit 1 index.
            control2 (Qubit or int): Control qubit 2 index.
            target (Qubit or int): Target qubit index.

        Returns:
            Instruction: CCNot instruction.

        Examples:
            >>> circ = Circuit().ccnot(0, 1, 2)
        """
        return Instruction(Gate.CCNot(), target=[control1, control2, target])
Beispiel #18
0
    def zz(target1: QubitInput, target2: QubitInput, angle: float) -> Instruction:
        """Registers this function into the circuit class.

        Args:
            target1 (Qubit or int): Target qubit 1 index.
            target2 (Qubit or int): Target qubit 2 index.
            angle (float): Angle in radians.

        Returns:
            Instruction: ZZ instruction.

        Examples:
            >>> circ = Circuit().zz(0, 1, 0.15)
        """
        return Instruction(Gate.ZZ(angle), target=[target1, target2])
Beispiel #19
0
    def cswap(control: QubitInput, target1: QubitInput, target2: QubitInput) -> Instruction:
        """Registers this function into the circuit class.

        Args:
            control (Qubit or int): Control qubit index
            target1 (Qubit or int): Target qubit 1 index.
            target2 (Qubit or int): Target qubit 2 index.

        Returns:
            Instruction: CSwap instruction.

        Examples:
            >>> circ = Circuit().cswap(0, 1, 2)
        """
        return Instruction(Gate.CSwap(), target=[control, target1, target2])
Beispiel #20
0
    def cphaseshift10(control: QubitInput, target: QubitInput, angle: float) -> Instruction:
        """Registers this function into the circuit class.

        Args:
            control (Qubit or int): Control qubit index.
            target (Qubit or int): Target qubit index.
            angle (float): Angle in radians.

        Returns:
            Instruction: CPhaseShift10 instruction.

        Examples:
            >>> circ = Circuit().cphaseshift10(0, 1, 0.15)
        """
        return Instruction(Gate.CPhaseShift10(angle), target=[control, target])
Beispiel #21
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
Beispiel #22
0
 def basis_rotation_gates(self) -> Tuple[Gate, ...]:
     return tuple([Gate.Z(), Gate.S(), Gate.H()])
Beispiel #23
0
        """Registers this function into the circuit class.

        Args:
            target (Qubit, int, or iterable of Qubit / int): Target qubit(s)

        Returns:
            Iterable[Instruction]: `Iterable` of H instructions.

        Examples:
            >>> circ = Circuit().h(0)
            >>> circ = Circuit().h([0, 1, 2])
        """
        return [Instruction(Gate.H(), target=qubit) for qubit in QubitSet(target)]


Gate.register_gate(H)


class I(Gate):  # noqa: E742, E261
    """Identity gate."""

    def __init__(self):
        super().__init__(qubit_count=1, ascii_symbols=["I"])

    def to_ir(self, target: QubitSet):
        return ir.I.construct(target=target[0])

    def to_matrix(self) -> np.ndarray:
        return np.eye(2, dtype=complex)

    @staticmethod
Beispiel #24
0
# 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.

import numpy as np
import pytest

from braket.circuits.circuit import Circuit
from braket.circuits.gate import Gate
from braket.circuits.instruction import Instruction
from braket.circuits.moments import Moments
from braket.circuits.noise import Noise
from braket.circuits.noise_helpers import apply_noise_to_gates, apply_noise_to_moments
from braket.circuits.qubit_set import QubitSet

invalid_data_noise_type = [Gate.X(), None, 1.5]
invalid_data_target_gates_type = [([-1, "foo"]), ([1.5, None, -1]), "X", ([Gate.X, "CNot"])]
invalid_data_target_qubits_value = [-1]
invalid_data_target_qubits_type = [1.5, "foo", ["foo", 1]]
invalid_data_target_unitary_value = [np.array([[0, 0], [1, 0]])]
invalid_data_target_unitary_type = [[[0, 1], [1, 0]]]


@pytest.fixture
def circuit_2qubit():
    return Circuit().x(0).y(1).x(0).x(1).cnot(0, 1)


@pytest.fixture
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]]))
Beispiel #25
0
 def basis_rotation_gates(self) -> Tuple[Gate]:
     return tuple([Gate.H()])
Beispiel #26
0
 def basis_rotation_gates(self) -> Tuple[Gate, ...]:
     return tuple([Gate.Ry(-math.pi / 4)])
Beispiel #27
0
 def basis_rotation_gates(self) -> Tuple[Gate]:
     return tuple([
         Gate.Unitary(
             matrix=self._get_eigendecomposition()["eigenvectors_conj_t"])
     ])