Exemple #1
0
 def circuit():
     ops[operation]
     return qml.expval(qml.Identity(wires=0))
Exemple #2
0
JUNK_INPUTS = [None, [], tuple(), 5.0, {"junk": -1}]

hamiltonians_with_expvals = [
    ((-0.6, ), (qml.PauliZ(0), ), [-0.6 * 1.0]),
    ((1.0, ), (qml.PauliX(0), ), [0.0]),
    ((0.5, 1.2), (qml.PauliZ(0), qml.PauliX(0)), [0.5 * 1.0, 0]),
    ((0.5, 1.2), (qml.PauliZ(0), qml.PauliX(1)), [0.5 * 1.0, 0]),
    ((0.5, 1.2), (qml.PauliZ(0), qml.PauliZ(0)), [0.5 * 1.0, 1.2 * 1.0]),
    ((0.5, 1.2), (qml.PauliZ(0), qml.PauliZ(1)), [0.5 * 1.0, 1.2 * 1.0]),
]

zero_hamiltonians_with_expvals = [
    ([], [], [0]),
    ((0, 0), (qml.PauliZ(0), qml.PauliZ(1)), [0]),
    ((0, 0, 0), (qml.PauliX(0) @ qml.Identity(1), qml.PauliX(0),
                 qml.PauliX(1)), [0]),
]

big_hamiltonian_coeffs = np.array([
    -0.04207898,
    0.17771287,
    0.17771287,
    -0.24274281,
    -0.24274281,
    0.17059738,
    0.04475014,
    -0.04475014,
    -0.04475014,
    0.04475014,
    0.12293305,
Exemple #3
0
# pylint: disable=pointless-statement
import pytest
from flaky import flaky
from scipy.sparse import coo_matrix

import pennylane as qml
from pennylane import numpy as np

pytestmark = pytest.mark.skip_unsupported

# ==========================================================
# Some useful global variables

# observables for which device support is tested
obs = {
    "Identity": qml.Identity(wires=[0]),
    "Hadamard": qml.Hadamard(wires=[0]),
    "Hermitian": qml.Hermitian(np.eye(2), wires=[0]),
    "PauliX": qml.PauliX(wires=[0]),
    "PauliY": qml.PauliY(wires=[0]),
    "PauliZ": qml.PauliZ(wires=[0]),
    "Projector": qml.Projector(np.array([1]), wires=[0]),
    "SparseHamiltonian": qml.SparseHamiltonian(coo_matrix(np.eye(8)), wires=[0, 1, 2]),
    "Hamiltonian": qml.Hamiltonian([1, 1], [qml.PauliZ(0), qml.PauliX(0)]),
}

all_obs = obs.keys()

# All qubit observables should be available to test in the device test suite
all_available_obs = qml.ops._qubit__obs__.copy()  # pylint: disable=protected-access
# Note that the identity is not technically a qubit observable
Exemple #4
0
 def circuit2():
     qml.templates.Permute(permutation2, wires=["z", "a", "k", "o"])
     return qml.expval(qml.Identity("z"))
Exemple #5
0
 def circuit(inp_):
     template(*inp_, wires=range(n_subsystems))
     return qml.expval(qml.Identity(0))
Exemple #6
0
 def circuit(x):
     """Test quantum function"""
     qml.Displacement(x, 0, wires=0)
     return qml.expval(qml.Identity(0))
Exemple #7
0
 def _circuit():
     ansatz(wires=list(range(num_qubits)))
     return qml.expval(qml.Identity(0))
Exemple #8
0
 def circuit():
     qml.RY(theta, wires=[0])
     qml.RY(phi, wires=[1])
     qml.CNOT(wires=[0, 1])
     return qml.expval(
         qml.Hermitian(obs, wires=[2, 0]) @ qml.Identity(1))
Exemple #9
0
 def circuit():
     qml.templates.BasisStatePreparation(basis_state, wires=range(3))
     return qml.expval(qml.Identity(0))
 def qubitstatevector_and_rot():
     qml.QubitStateVector(state, wires=[0])
     qml.Rot(a, b, c, wires=[0])
     return qml.expval(qml.Identity(0))
 def basisstate():
     qml.BasisState(state, wires=[0, 1, 2, 3])
     return qml.expval(qml.Identity(0))
Exemple #12
0
 def circuit(a, b, c):
     qml.RY(a, wires=0)
     qml.RY(b, wires=1)
     qml.CNOT(wires=[0, 1])
     return expval(qml.Hermitian(A, 0) @ qml.Identity(1))
Exemple #13
0
 def circuit(a, b, c):
     ansatz(a, b, c)
     return expval(qml.PauliZ(0) @ qml.Identity(1) @ qml.PauliZ(2))
Exemple #14
0
class TestTensor:
    """Unit tests for the Tensor class"""
    def test_construct(self):
        """Test construction of a tensor product"""
        X = qml.PauliX(0)
        Y = qml.PauliY(2)
        T = Tensor(X, Y)
        assert T.obs == [X, Y]

        T = Tensor(T, Y)
        assert T.obs == [X, Y, Y]

        with pytest.raises(
                ValueError,
                match="Can only perform tensor products between observables"):
            Tensor(T, qml.CNOT(wires=[0, 1]))

    def test_name(self):
        """Test that the names of the observables are
        returned as expected"""
        X = qml.PauliX(0)
        Y = qml.PauliY(2)
        t = Tensor(X, Y)
        assert t.name == [X.name, Y.name]

    def test_num_wires(self):
        """Test that the correct number of wires is returned"""
        p = np.array([0.5])
        X = qml.PauliX(0)
        Y = qml.Hermitian(p, wires=[1, 2])
        t = Tensor(X, Y)
        assert t.num_wires == 3

    def test_wires(self):
        """Test that the correct nested list of wires is returned"""
        p = np.array([0.5])
        X = qml.PauliX(0)
        Y = qml.Hermitian(p, wires=[1, 2])
        t = Tensor(X, Y)
        assert t.wires == [0, 1, 2]

    def test_params(self):
        """Test that the correct flattened list of parameters is returned"""
        p = np.array([0.5])
        X = qml.PauliX(0)
        Y = qml.Hermitian(p, wires=[1, 2])
        t = Tensor(X, Y)
        assert t.params == [p]

    def test_num_params(self):
        """Test that the correct number of parameters is returned"""
        p = np.array([0.5])
        X = qml.PauliX(0)
        Y = qml.Hermitian(p, wires=[1, 2])
        Z = qml.Hermitian(p, wires=[1, 2])
        t = Tensor(X, Y, Z)
        assert t.num_params == 2

    def test_parameters(self):
        """Test that the correct nested list of parameters is returned"""
        p = np.array([0.5])
        X = qml.PauliX(0)
        Y = qml.Hermitian(p, wires=[1, 2])
        t = Tensor(X, Y)
        assert t.parameters == [[], [p]]

    def test_multiply_obs(self):
        """Test that multiplying two observables
        produces a tensor"""
        X = qml.PauliX(0)
        Y = qml.Hadamard(2)
        t = X @ Y
        assert isinstance(t, Tensor)
        assert t.obs == [X, Y]

    def test_multiply_obs_tensor(self):
        """Test that multiplying an observable by a tensor
        produces a tensor"""
        X = qml.PauliX(0)
        Y = qml.Hadamard(2)
        Z = qml.PauliZ(1)

        t = X @ Y
        t = Z @ t

        assert isinstance(t, Tensor)
        assert t.obs == [Z, X, Y]

    def test_multiply_tensor_obs(self):
        """Test that multiplying a tensor by an observable
        produces a tensor"""
        X = qml.PauliX(0)
        Y = qml.Hadamard(2)
        Z = qml.PauliZ(1)

        t = X @ Y
        t = t @ Z

        assert isinstance(t, Tensor)
        assert t.obs == [X, Y, Z]

    def test_multiply_tensor_tensor(self):
        """Test that multiplying a tensor by a tensor
        produces a tensor"""
        X = qml.PauliX(0)
        Y = qml.PauliY(2)
        Z = qml.PauliZ(1)
        H = qml.Hadamard(3)

        t1 = X @ Y
        t2 = Z @ H
        t = t2 @ t1

        assert isinstance(t, Tensor)
        assert t.obs == [Z, H, X, Y]

    def test_multiply_tensor_in_place(self):
        """Test that multiplying a tensor in-place
        produces a tensor"""
        X = qml.PauliX(0)
        Y = qml.PauliY(2)
        Z = qml.PauliZ(1)
        H = qml.Hadamard(3)

        t = X
        t @= Y
        t @= Z @ H

        assert isinstance(t, Tensor)
        assert t.obs == [X, Y, Z, H]

    def test_operation_multiply_invalid(self):
        """Test that an exception is raised if an observable
        is multiplied by an operation"""
        X = qml.PauliX(0)
        Y = qml.CNOT(wires=[0, 1])
        Z = qml.PauliZ(0)

        with pytest.raises(
                ValueError,
                match="Can only perform tensor products between observables"):
            X @ Y

        with pytest.raises(
                ValueError,
                match="Can only perform tensor products between observables"):
            T = X @ Z
            T @ Y

        with pytest.raises(
                ValueError,
                match="Can only perform tensor products between observables"):
            T = X @ Z
            Y @ T

    def test_eigvals(self):
        """Test that the correct eigenvalues are returned for the Tensor"""
        X = qml.PauliX(0)
        Y = qml.PauliY(2)
        t = Tensor(X, Y)
        assert np.array_equal(t.eigvals, np.kron([1, -1], [1, -1]))

        # test that the eigvals are now cached and not recalculated
        assert np.array_equal(t._eigvals_cache, t.eigvals)

    @pytest.mark.usefixtures("tear_down_hermitian")
    def test_eigvals_hermitian(self, tol):
        """Test that the correct eigenvalues are returned for the Tensor containing an Hermitian observable"""
        X = qml.PauliX(0)
        hamiltonian = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1],
                                [0, 0, 1, 0]])
        Herm = qml.Hermitian(hamiltonian, wires=[1, 2])
        t = Tensor(X, Herm)
        d = np.kron(np.array([1., -1.]), np.array([-1., 1., 1., 1.]))
        t = t.eigvals
        assert np.allclose(t, d, atol=tol, rtol=0)

    def test_eigvals_identity(self, tol):
        """Test that the correct eigenvalues are returned for the Tensor containing an Identity"""
        X = qml.PauliX(0)
        Iden = qml.Identity(1)
        t = Tensor(X, Iden)
        d = np.kron(np.array([1., -1.]), np.array([1., 1.]))
        t = t.eigvals
        assert np.allclose(t, d, atol=tol, rtol=0)

    def test_eigvals_identity_and_hermitian(self, tol):
        """Test that the correct eigenvalues are returned for the Tensor containing
        multiple types of observables"""
        H = np.diag([1, 2, 3, 4])
        O = qml.PauliX(0) @ qml.Identity(2) @ qml.Hermitian(H, wires=[4, 5])
        res = O.eigvals
        expected = np.kron(np.array([1., -1.]),
                           np.kron(np.array([1., 1.]), np.arange(1, 5)))
        assert np.allclose(res, expected, atol=tol, rtol=0)

    def test_diagonalizing_gates(self, tol):
        """Test that the correct diagonalizing gate set is returned for a Tensor of observables"""
        H = np.diag([1, 2, 3, 4])
        O = qml.PauliX(0) @ qml.Identity(2) @ qml.PauliY(1) @ qml.Hermitian(
            H, [5, 6])

        res = O.diagonalizing_gates()

        # diagonalize the PauliX on wire 0 (H.X.H = Z)
        assert isinstance(res[0], qml.Hadamard)
        assert res[0].wires == [0]

        # diagonalize the PauliY on wire 1 (U.Y.U^\dagger = Z
        # where U = HSZ).
        assert isinstance(res[1], qml.PauliZ)
        assert res[1].wires == [1]
        assert isinstance(res[2], qml.S)
        assert res[2].wires == [1]
        assert isinstance(res[3], qml.Hadamard)
        assert res[3].wires == [1]

        # diagonalize the Hermitian observable on wires 5, 6
        assert isinstance(res[4], qml.QubitUnitary)
        assert res[4].wires == [5, 6]

        O = O @ qml.Hadamard(4)
        res = O.diagonalizing_gates()

        # diagonalize the Hadamard observable on wire 4
        # (RY(-pi/4).H.RY(pi/4) = Z)
        assert isinstance(res[-1], qml.RY)
        assert res[-1].wires == [4]
        assert np.allclose(res[-1].parameters, -np.pi / 4, atol=tol, rtol=0)

    def test_diagonalizing_gates_numerically_diagonalizes(self, tol):
        """Test that the diagonalizing gate set numerically
        diagonalizes the tensor observable"""

        # create a tensor observable acting on consecutive wires
        H = np.diag([1, 2, 3, 4])
        O = qml.PauliX(0) @ qml.PauliY(1) @ qml.Hermitian(H, [2, 3])

        O_mat = O.matrix
        diag_gates = O.diagonalizing_gates()

        # group the diagonalizing gates based on what wires they act on
        U_list = []
        for _, g in itertools.groupby(diag_gates, lambda x: x.wires):
            # extract the matrices of each diagonalizing gate
            mats = [i.matrix for i in g]

            # Need to revert the order in which the matrices are applied such that they adhere to the order
            # of matrix multiplication
            # E.g. for PauliY: [PauliZ(wires=self.wires), S(wires=self.wires), Hadamard(wires=self.wires)]
            # becomes Hadamard @ S @ PauliZ, where @ stands for matrix multiplication
            mats = mats[::-1]

            if len(mats) > 1:
                # multiply all unitaries together before appending
                mats = [multi_dot(mats)]

            # append diagonalizing unitary for specific wire to U_list
            U_list.append(mats[0])

        # since the test is assuming consecutive wires for each observable
        # in the tensor product, it is sufficient to Kronecker product
        # the entire list.
        U = functools.reduce(np.kron, U_list)

        res = U @ O_mat @ U.conj().T
        expected = np.diag(O.eigvals)

        # once diagonalized by U, the result should be a diagonal
        # matrix of the eigenvalues.
        assert np.allclose(res, expected, atol=tol, rtol=0)

    def test_tensor_matrix(self, tol):
        """Test that the tensor product matrix method returns
        the correct result"""
        H = np.diag([1, 2, 3, 4])
        O = qml.PauliX(0) @ qml.PauliY(1) @ qml.Hermitian(H, [2, 3])

        res = O.matrix
        expected = np.kron(qml.PauliY._matrix(), H)
        expected = np.kron(qml.PauliX._matrix(), expected)

        assert np.allclose(res, expected, atol=tol, rtol=0)

    def test_multiplication_matrix(self, tol):
        """If using the ``@`` operator on two observables acting on the
        same wire, the tensor class should treat this as matrix multiplication."""
        O = qml.PauliX(0) @ qml.PauliX(0)

        res = O.matrix
        expected = qml.PauliX._matrix() @ qml.PauliX._matrix()

        assert np.allclose(res, expected, atol=tol, rtol=0)

    herm_matrix = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0],
                            [0, 0, 0, 1]])

    tensor_obs = [
        (qml.PauliZ(0) @ qml.Identity(1) @ qml.PauliZ(2),
         [qml.PauliZ(0), qml.PauliZ(2)]),
        (qml.Identity(0) @ qml.PauliX(1) @ qml.Identity(2) @ qml.PauliZ(3)
         @ qml.PauliZ(4) @ qml.Identity(5),
         [qml.PauliX(1), qml.PauliZ(3),
          qml.PauliZ(4)]),

        # List containing single observable is returned
        (qml.PauliZ(0) @ qml.Identity(1), [qml.PauliZ(0)]),
        (qml.Identity(0) @ qml.PauliX(1) @ qml.Identity(2), [qml.PauliX(1)]),
        (qml.Identity(0) @ qml.Identity(1), [qml.Identity(0)]),
        (qml.Identity(0) @ qml.Identity(1) @ qml.Hermitian(herm_matrix,
                                                           wires=[2, 3]),
         [qml.Hermitian(herm_matrix, wires=[2, 3])])
    ]

    @pytest.mark.parametrize("tensor_observable, expected", tensor_obs)
    def test_non_identity_obs(self, tensor_observable, expected):
        """Tests that the non_identity_obs property returns a list that contains no Identity instances."""

        O = tensor_observable
        for idx, obs in enumerate(O.non_identity_obs):
            assert type(obs) == type(expected[idx])
            assert obs.wires == expected[idx].wires

    tensor_obs_pruning = [
        (qml.PauliZ(0) @ qml.Identity(1) @ qml.PauliZ(2),
         qml.PauliZ(0) @ qml.PauliZ(2)),
        (qml.Identity(0) @ qml.PauliX(1)
         @ qml.Identity(2) @ qml.PauliZ(3) @ qml.PauliZ(4) @ qml.Identity(5),
         qml.PauliX(1) @ qml.PauliZ(3) @ qml.PauliZ(4)),
        # Single observable is returned
        (qml.PauliZ(0) @ qml.Identity(1), qml.PauliZ(0)),
        (qml.Identity(0) @ qml.PauliX(1) @ qml.Identity(2), qml.PauliX(1)),
        (qml.Identity(0) @ qml.Identity(1), qml.Identity(0)),
        (qml.Identity(0) @ qml.Identity(1), qml.Identity(0)),
        (qml.Identity(0) @ qml.Identity(1) @ qml.Hermitian(
            herm_matrix, wires=[2, 3]), qml.Hermitian(herm_matrix,
                                                      wires=[2, 3]))
    ]

    @pytest.mark.parametrize("tensor_observable, expected", tensor_obs_pruning)
    @pytest.mark.parametrize("statistics", [qml.expval, qml.var, qml.sample])
    def test_prune(self, tensor_observable, expected, statistics):
        """Tests that the prune method returns the expected Tensor or single non-Tensor Observable."""
        O = statistics(tensor_observable)
        O_expected = statistics(expected)

        O_pruned = O.prune()
        assert type(O_pruned) == type(expected)
        assert O_pruned.wires == expected.wires
        assert O_pruned.return_type == O_expected.return_type
Exemple #15
0
 def circuit(*inp):
     template(*inp, **hyperp)
     return qml.expval(qml.Identity(0))
Exemple #16
0
 def circuit2():
     qml.templates.BasisStatePreparation(basis_state,
                                         wires=["z", "a", "k"])
     return qml.expval(qml.Identity("z"))
 def circuit(x):
     """Test quantum function"""
     qml.RX(x, wires=0)
     return qml.expval(qml.Identity(0))
Exemple #18
0
def edge_driver(graph, reward):
    r"""Returns the edge-driver cost Hamiltonian.

    Given some graph, :math:`G` with each node representing a wire, and a binary
    colouring where each node/wire is assigned either :math:`|0\rangle` or :math:`|1\rangle`, the edge driver
    cost Hamiltonian will assign a lower energy to edges represented by qubit states with endpoint colourings
    supplied in ``reward``.

    For instance, if ``reward`` is ``["11"]``, then edges
    with both endpoints coloured as ``1`` (the state :math:`|11\rangle`) will be assigned a lower energy, while
    the other colourings  (``"00"``, ``"10"``, and ``"01"`` corresponding to states
    :math:`|00\rangle`, :math:`|10\rangle`, and :math:`|10\rangle`, respectively) will be assigned a higher energy.

    See usage details for more information.

    Args:
         graph (nx.Graph): The graph on which the Hamiltonian is defined
         reward (list[str]): The list of two-bit bitstrings that are assigned a lower energy by the Hamiltonian

    Returns:
        .Hamiltonian:

    **Example**

    >>> import networkx as nx
    >>> graph = nx.Graph([(0, 1), (1, 2)])
    >>> hamiltonian = qaoa.edge_driver(graph, ["11", "10", "01"])
    >>> print(hamiltonian)
      (0.25) [Z0]
    + (0.25) [Z1]
    + (0.25) [Z1]
    + (0.25) [Z2]
    + (0.25) [Z0 Z1]
    + (0.25) [Z1 Z2]

    In the above example, ``"11"``, ``"10"``, and ``"01"`` are assigned a lower
    energy than ``"00"``. For example, a quick calculation of expectation values gives us:

    .. math:: \langle 000 | H | 000 \rangle \ = \ 1.5
    .. math:: \langle 100 | H | 100 \rangle \ = \ 0.5
    .. math:: \langle 110 | H | 110\rangle \ = \ -0.5

    In the first example, both vertex pairs are not in ``reward``. In the second example, one pair is in ``reward`` and
    the other is not. Finally, in the third example, both pairs are in ``reward``.

    .. UsageDetails::

        The goal of many combinatorial problems that can be solved with QAOA is to
        find a `Graph colouring <https://en.wikipedia.org/wiki/Graph_coloring>`__ of some supplied
        graph :math:`G`, that minimizes some cost function. With QAOA, it is natural to consider the class
        of graph colouring problems that only admit two colours, as we can easily encode these two colours
        using the :math:`|1\rangle` and :math:`|0\rangle` states of qubits. Therefore, given
        some graph :math:`G`, each edge of the graph can be described by a pair of qubits, :math:`|00\rangle`,
        :math:`|01\rangle`, :math:`|10\rangle`, or :math:`|11\rangle`, corresponding to the colourings of its endpoints.

        When constructing QAOA cost functions, one must "penalize" certain states of the graph, and "reward"
        others, by assigning higher and lower energies to these respective configurations. Given a set of vertex-colour
        pairs (which each describe a possible  state of a graph edge), the ``edge_driver()``
        function outputs a Hamiltonian that rewards the pairs in the set, and penalizes the others.

        For example, given the reward set: :math:`\{|00\rangle, \ |01\rangle, \ |10\rangle\}` and the graph :math:`G`,
        the ``edge_driver()`` function will output the following Hamiltonian:

        .. math:: H \ = \ \frac{1}{4} \displaystyle\sum_{(i, j) \in E(G)} \big( Z_{i} Z_{j} \ - \ Z_{i} \ - \ Z_{j} \big)

        where :math:`E(G)` is the set of edges of :math:`G`, and :math:`Z_i` is the Pauli-Z operator acting on the
        :math:`i`-th wire. As can be checked, this Hamiltonian assigns an energy of :math:`-1/4` to the states
        :math:`|00\rangle`, :math:`|01\rangle` and :math:`|10\rangle`, and an energy of :math:`3/4` to the state
        :math:`|11\rangle`.

        .. Note::

            ``reward`` must always contain both :math:`|01\rangle` and :math:`|10\rangle`, or neither of the two.
            Within an undirected graph, there is no notion of "order"
            of edge endpoints, so these two states are effectively the same. Therefore, there is no well-defined way to
            penalize one and reward the other.

        .. Note::

            The absolute difference in energy between colourings in ``reward`` and colourings in its
            complement is always :math:`1`.

    """

    allowed = ["00", "01", "10", "11"]

    if not all(e in allowed for e in reward):
        raise ValueError(
            "Encountered invalid entry in 'reward', expected 2-bit bitstrings."
        )

    if "01" in reward and "10" not in reward or "10" in reward and "01" not in reward:
        raise ValueError(
            "'reward' cannot contain either '10' or '01', must contain neither or both."
        )

    if not isinstance(graph, nx.Graph):
        raise ValueError("Input graph must be a nx.Graph, got {}".format(
            type(graph).__name__))

    coeffs = []
    ops = []

    if len(reward) == 0 or len(reward) == 4:
        coeffs = [1 for _ in graph.nodes]
        ops = [qml.Identity(v) for v in graph.nodes]

    else:

        reward = list(set(reward) - {"01"})
        sign = -1

        if len(reward) == 2:
            reward = list({"00", "10", "11"} - set(reward))
            sign = 1

        reward = reward[0]

        if reward == "00":
            for e in graph.edges:
                coeffs.extend([0.25 * sign, 0.25 * sign, 0.25 * sign])
                ops.extend([
                    qml.PauliZ(e[0]) @ qml.PauliZ(e[1]),
                    qml.PauliZ(e[0]),
                    qml.PauliZ(e[1])
                ])

        if reward == "10":
            for e in graph.edges:
                coeffs.append(-0.5 * sign)
                ops.append(qml.PauliZ(e[0]) @ qml.PauliZ(e[1]))

        if reward == "11":
            for e in graph.edges:
                coeffs.extend([0.25 * sign, -0.25 * sign, -0.25 * sign])
                ops.extend([
                    qml.PauliZ(e[0]) @ qml.PauliZ(e[1]),
                    qml.PauliZ(e[0]),
                    qml.PauliZ(e[1])
                ])

    return qml.Hamiltonian(coeffs, ops)
class TestRepresentationResolver:
    """Test the RepresentationResolver class."""
    @pytest.mark.parametrize(
        "list,element,index,list_after",
        [
            ([1, 2, 3], 2, 1, [1, 2, 3]),
            ([1, 2, 2, 3], 2, 1, [1, 2, 2, 3]),
            ([1, 2, 3], 4, 3, [1, 2, 3, 4]),
        ],
    )
    def test_index_of_array_or_append(self, list, element, index, list_after):
        """Test the method index_of_array_or_append."""

        assert RepresentationResolver.index_of_array_or_append(element,
                                                               list) == index
        assert list == list_after

    @pytest.mark.parametrize("par,expected", [
        (3, "3"),
        (5.236422, "5.236"),
    ])
    def test_single_parameter_representation(self,
                                             unicode_representation_resolver,
                                             par, expected):
        """Test that single parameters are properly resolved."""
        assert unicode_representation_resolver.single_parameter_representation(
            par) == expected

    def test_single_parameter_representation_variable(
            self, unicode_representation_resolver, variable):
        """Test that variables are properly resolved."""

        assert unicode_representation_resolver.single_parameter_representation(
            variable) == "2"

    def test_single_parameter_representation_kwarg_variable(
            self, unicode_representation_resolver, kwarg_variable):
        """Test that kwarg variables are properly resolved."""

        assert (unicode_representation_resolver.
                single_parameter_representation(kwarg_variable) == "1")

    @pytest.mark.parametrize("par,expected", [
        (3, "3"),
        (5.236422, "5.236"),
    ])
    def test_single_parameter_representation_varnames(
            self, unicode_representation_resolver_varnames, par, expected):
        """Test that single parameters are properly resolved when show_variable_names is True."""
        assert (unicode_representation_resolver_varnames.
                single_parameter_representation(par) == expected)

    def test_single_parameter_representation_variable_varnames(
            self, unicode_representation_resolver_varnames, variable):
        """Test that variables are properly resolved when show_variable_names is True."""

        assert (unicode_representation_resolver_varnames.
                single_parameter_representation(variable) == "test")

    def test_single_parameter_representation_kwarg_variable_varnames(
            self, unicode_representation_resolver_varnames, kwarg_variable):
        """Test that kwarg variables are properly resolved when show_variable_names is True."""

        assert (
            unicode_representation_resolver_varnames.
            single_parameter_representation(kwarg_variable) == "kwarg_test")

    @pytest.mark.parametrize(
        "op,wire,target",
        [
            (qml.PauliX(wires=[1]), 1, "X"),
            (qml.CNOT(wires=[0, 1]), 1, "X"),
            (qml.CNOT(wires=[0, 1]), 0, "C"),
            (qml.Toffoli(wires=[0, 2, 1]), 1, "X"),
            (qml.Toffoli(wires=[0, 2, 1]), 0, "C"),
            (qml.Toffoli(wires=[0, 2, 1]), 2, "C"),
            (qml.CSWAP(wires=[0, 2, 1]), 1, "SWAP"),
            (qml.CSWAP(wires=[0, 2, 1]), 2, "SWAP"),
            (qml.CSWAP(wires=[0, 2, 1]), 0, "C"),
            (qml.PauliY(wires=[1]), 1, "Y"),
            (qml.PauliZ(wires=[1]), 1, "Z"),
            (qml.CZ(wires=[0, 1]), 1, "Z"),
            (qml.CZ(wires=[0, 1]), 0, "C"),
            (qml.Identity(wires=[1]), 1, "I"),
            (qml.Hadamard(wires=[1]), 1, "H"),
            (qml.CRX(3.14, wires=[0, 1]), 1, "RX(3.14)"),
            (qml.CRX(3.14, wires=[0, 1]), 0, "C"),
            (qml.CRY(3.14, wires=[0, 1]), 1, "RY(3.14)"),
            (qml.CRY(3.14, wires=[0, 1]), 0, "C"),
            (qml.CRZ(3.14, wires=[0, 1]), 1, "RZ(3.14)"),
            (qml.CRZ(3.14, wires=[0, 1]), 0, "C"),
            (qml.CRot(3.14, 2.14, 1.14, wires=[0, 1
                                               ]), 1, "Rot(3.14, 2.14, 1.14)"),
            (qml.CRot(3.14, 2.14, 1.14, wires=[0, 1]), 0, "C"),
            (qml.PhaseShift(3.14, wires=[0]), 0, "Rϕ(3.14)"),
            (qml.Beamsplitter(1, 2, wires=[0, 1]), 1, "BS(1, 2)"),
            (qml.Beamsplitter(1, 2, wires=[0, 1]), 0, "BS(1, 2)"),
            (qml.Squeezing(1, 2, wires=[1]), 1, "S(1, 2)"),
            (qml.TwoModeSqueezing(1, 2, wires=[0, 1]), 1, "S(1, 2)"),
            (qml.TwoModeSqueezing(1, 2, wires=[0, 1]), 0, "S(1, 2)"),
            (qml.Displacement(1, 2, wires=[1]), 1, "D(1, 2)"),
            (qml.NumberOperator(wires=[1]), 1, "n"),
            (qml.Rotation(3.14, wires=[1]), 1, "R(3.14)"),
            (qml.ControlledAddition(3.14, wires=[0, 1]), 1, "X(3.14)"),
            (qml.ControlledAddition(3.14, wires=[0, 1]), 0, "C"),
            (qml.ControlledPhase(3.14, wires=[0, 1]), 1, "Z(3.14)"),
            (qml.ControlledPhase(3.14, wires=[0, 1]), 0, "C"),
            (qml.ThermalState(3, wires=[1]), 1, "Thermal(3)"),
            (
                qml.GaussianState(
                    np.array([1, 2]), np.array([[2, 0], [0, 2]]), wires=[1]),
                1,
                "Gaussian(M0,M1)",
            ),
            (qml.QuadraticPhase(3.14, wires=[1]), 1, "P(3.14)"),
            (qml.RX(3.14, wires=[1]), 1, "RX(3.14)"),
            (qml.S(wires=[2]), 2, "S"),
            (qml.T(wires=[2]), 2, "T"),
            (qml.RX(3.14, wires=[1]), 1, "RX(3.14)"),
            (qml.RY(3.14, wires=[1]), 1, "RY(3.14)"),
            (qml.RZ(3.14, wires=[1]), 1, "RZ(3.14)"),
            (qml.Rot(3.14, 2.14, 1.14, wires=[1]), 1, "Rot(3.14, 2.14, 1.14)"),
            (qml.U1(3.14, wires=[1]), 1, "U1(3.14)"),
            (qml.U2(3.14, 2.14, wires=[1]), 1, "U2(3.14, 2.14)"),
            (qml.U3(3.14, 2.14, 1.14, wires=[1]), 1, "U3(3.14, 2.14, 1.14)"),
            (qml.BasisState(np.array([0, 1, 0]), wires=[1, 2, 3]), 1, "|0⟩"),
            (qml.BasisState(np.array([0, 1, 0]), wires=[1, 2, 3]), 2, "|1⟩"),
            (qml.BasisState(np.array([0, 1, 0]), wires=[1, 2, 3]), 3, "|0⟩"),
            (qml.QubitStateVector(np.array([0, 1, 0, 0]),
                                  wires=[1, 2]), 1, "QubitStateVector(M0)"),
            (qml.QubitStateVector(np.array([0, 1, 0, 0]),
                                  wires=[1, 2]), 2, "QubitStateVector(M0)"),
            (qml.QubitUnitary(np.eye(2), wires=[1]), 1, "U0"),
            (qml.QubitUnitary(np.eye(4), wires=[1, 2]), 2, "U0"),
            (qml.Kerr(3.14, wires=[1]), 1, "Kerr(3.14)"),
            (qml.CrossKerr(3.14, wires=[1, 2]), 1, "CrossKerr(3.14)"),
            (qml.CrossKerr(3.14, wires=[1, 2]), 2, "CrossKerr(3.14)"),
            (qml.CubicPhase(3.14, wires=[1]), 1, "V(3.14)"),
            (qml.Interferometer(np.eye(4), wires=[1, 3
                                                  ]), 1, "Interferometer(M0)"),
            (qml.Interferometer(np.eye(4), wires=[1, 3
                                                  ]), 3, "Interferometer(M0)"),
            (qml.CatState(3.14, 2.14, 1,
                          wires=[1]), 1, "CatState(3.14, 2.14, 1)"),
            (qml.CoherentState(3.14, 2.14,
                               wires=[1]), 1, "CoherentState(3.14, 2.14)"),
            (
                qml.FockDensityMatrix(np.kron(np.eye(4), np.eye(4)),
                                      wires=[1, 2]),
                1,
                "FockDensityMatrix(M0)",
            ),
            (
                qml.FockDensityMatrix(np.kron(np.eye(4), np.eye(4)),
                                      wires=[1, 2]),
                2,
                "FockDensityMatrix(M0)",
            ),
            (
                qml.DisplacedSqueezedState(3.14, 2.14, 1.14, 0.14, wires=[1]),
                1,
                "DisplacedSqueezedState(3.14, 2.14, 1.14, 0.14)",
            ),
            (qml.FockState(7, wires=[1]), 1, "|7⟩"),
            (qml.FockStateVector(np.array([4, 5, 7]), wires=[1, 2, 3
                                                             ]), 1, "|4⟩"),
            (qml.FockStateVector(np.array([4, 5, 7]), wires=[1, 2, 3
                                                             ]), 2, "|5⟩"),
            (qml.FockStateVector(np.array([4, 5, 7]), wires=[1, 2, 3
                                                             ]), 3, "|7⟩"),
            (qml.SqueezedState(3.14, 2.14,
                               wires=[1]), 1, "SqueezedState(3.14, 2.14)"),
            (qml.Hermitian(np.eye(4), wires=[1, 2]), 1, "H0"),
            (qml.Hermitian(np.eye(4), wires=[1, 2]), 2, "H0"),
            (qml.X(wires=[1]), 1, "x"),
            (qml.P(wires=[1]), 1, "p"),
            (qml.FockStateProjector(np.array([4, 5, 7]),
                                    wires=[1, 2, 3]), 1, "|4,5,7╳4,5,7|"),
            (
                qml.PolyXP(np.array([1, 2, 0, -1.3, 6]), wires=[1]),
                2,
                "1+2x₀-1.3x₁+6p₁",
            ),
            (
                qml.PolyXP(np.array([[1.2, 2.3, 4.5], [-1.2, 1.2, -1.5],
                                     [-1.3, 4.5, 2.3]]),
                           wires=[1]),
                1,
                "1.2+1.1x₀+3.2p₀+1.2x₀²+2.3p₀²+3x₀p₀",
            ),
            (
                qml.PolyXP(
                    np.array([
                        [1.2, 2.3, 4.5, 0, 0],
                        [-1.2, 1.2, -1.5, 0, 0],
                        [-1.3, 4.5, 2.3, 0, 0],
                        [0, 2.6, 0, 0, 0],
                        [0, 0, 0, -4.7, -1.0],
                    ]),
                    wires=[1],
                ),
                1,
                "1.2+1.1x₀+3.2p₀+1.2x₀²+2.3p₀²+3x₀p₀+2.6x₀x₁-p₁²-4.7x₁p₁",
            ),
            (qml.QuadOperator(3.14, wires=[1]), 1, "cos(3.14)x+sin(3.14)p"),
        ],
    )
    def test_operator_representation_unicode(self,
                                             unicode_representation_resolver,
                                             op, wire, target):
        """Test that an Operator instance is properly resolved."""
        assert unicode_representation_resolver.operator_representation(
            op, wire) == target

    @pytest.mark.parametrize(
        "op,wire,target",
        [
            (qml.PauliX(wires=[1]), 1, "X"),
            (qml.CNOT(wires=[0, 1]), 1, "X"),
            (qml.CNOT(wires=[0, 1]), 0, "C"),
            (qml.Toffoli(wires=[0, 2, 1]), 1, "X"),
            (qml.Toffoli(wires=[0, 2, 1]), 0, "C"),
            (qml.Toffoli(wires=[0, 2, 1]), 2, "C"),
            (qml.CSWAP(wires=[0, 2, 1]), 1, "SWAP"),
            (qml.CSWAP(wires=[0, 2, 1]), 2, "SWAP"),
            (qml.CSWAP(wires=[0, 2, 1]), 0, "C"),
            (qml.PauliY(wires=[1]), 1, "Y"),
            (qml.PauliZ(wires=[1]), 1, "Z"),
            (qml.CZ(wires=[0, 1]), 1, "Z"),
            (qml.CZ(wires=[0, 1]), 0, "C"),
            (qml.Identity(wires=[1]), 1, "I"),
            (qml.Hadamard(wires=[1]), 1, "H"),
            (qml.CRX(3.14, wires=[0, 1]), 1, "RX(3.14)"),
            (qml.CRX(3.14, wires=[0, 1]), 0, "C"),
            (qml.CRY(3.14, wires=[0, 1]), 1, "RY(3.14)"),
            (qml.CRY(3.14, wires=[0, 1]), 0, "C"),
            (qml.CRZ(3.14, wires=[0, 1]), 1, "RZ(3.14)"),
            (qml.CRZ(3.14, wires=[0, 1]), 0, "C"),
            (qml.CRot(3.14, 2.14, 1.14, wires=[0, 1
                                               ]), 1, "Rot(3.14, 2.14, 1.14)"),
            (qml.CRot(3.14, 2.14, 1.14, wires=[0, 1]), 0, "C"),
            (qml.PhaseShift(3.14, wires=[0]), 0, "Rϕ(3.14)"),
            (qml.Beamsplitter(1, 2, wires=[0, 1]), 1, "BS(1, 2)"),
            (qml.Beamsplitter(1, 2, wires=[0, 1]), 0, "BS(1, 2)"),
            (qml.Squeezing(1, 2, wires=[1]), 1, "S(1, 2)"),
            (qml.TwoModeSqueezing(1, 2, wires=[0, 1]), 1, "S(1, 2)"),
            (qml.TwoModeSqueezing(1, 2, wires=[0, 1]), 0, "S(1, 2)"),
            (qml.Displacement(1, 2, wires=[1]), 1, "D(1, 2)"),
            (qml.NumberOperator(wires=[1]), 1, "n"),
            (qml.Rotation(3.14, wires=[1]), 1, "R(3.14)"),
            (qml.ControlledAddition(3.14, wires=[0, 1]), 1, "X(3.14)"),
            (qml.ControlledAddition(3.14, wires=[0, 1]), 0, "C"),
            (qml.ControlledPhase(3.14, wires=[0, 1]), 1, "Z(3.14)"),
            (qml.ControlledPhase(3.14, wires=[0, 1]), 0, "C"),
            (qml.ThermalState(3, wires=[1]), 1, "Thermal(3)"),
            (
                qml.GaussianState(
                    np.array([1, 2]), np.array([[2, 0], [0, 2]]), wires=[1]),
                1,
                "Gaussian(M0,M1)",
            ),
            (qml.QuadraticPhase(3.14, wires=[1]), 1, "P(3.14)"),
            (qml.RX(3.14, wires=[1]), 1, "RX(3.14)"),
            (qml.S(wires=[2]), 2, "S"),
            (qml.T(wires=[2]), 2, "T"),
            (qml.RX(3.14, wires=[1]), 1, "RX(3.14)"),
            (qml.RY(3.14, wires=[1]), 1, "RY(3.14)"),
            (qml.RZ(3.14, wires=[1]), 1, "RZ(3.14)"),
            (qml.Rot(3.14, 2.14, 1.14, wires=[1]), 1, "Rot(3.14, 2.14, 1.14)"),
            (qml.U1(3.14, wires=[1]), 1, "U1(3.14)"),
            (qml.U2(3.14, 2.14, wires=[1]), 1, "U2(3.14, 2.14)"),
            (qml.U3(3.14, 2.14, 1.14, wires=[1]), 1, "U3(3.14, 2.14, 1.14)"),
            (qml.BasisState(np.array([0, 1, 0]), wires=[1, 2, 3]), 1, "|0>"),
            (qml.BasisState(np.array([0, 1, 0]), wires=[1, 2, 3]), 2, "|1>"),
            (qml.BasisState(np.array([0, 1, 0]), wires=[1, 2, 3]), 3, "|0>"),
            (qml.QubitStateVector(np.array([0, 1, 0, 0]),
                                  wires=[1, 2]), 1, "QubitStateVector(M0)"),
            (qml.QubitStateVector(np.array([0, 1, 0, 0]),
                                  wires=[1, 2]), 2, "QubitStateVector(M0)"),
            (qml.QubitUnitary(np.eye(2), wires=[1]), 1, "U0"),
            (qml.QubitUnitary(np.eye(4), wires=[1, 2]), 2, "U0"),
            (qml.Kerr(3.14, wires=[1]), 1, "Kerr(3.14)"),
            (qml.CrossKerr(3.14, wires=[1, 2]), 1, "CrossKerr(3.14)"),
            (qml.CrossKerr(3.14, wires=[1, 2]), 2, "CrossKerr(3.14)"),
            (qml.CubicPhase(3.14, wires=[1]), 1, "V(3.14)"),
            (qml.Interferometer(np.eye(4), wires=[1, 3
                                                  ]), 1, "Interferometer(M0)"),
            (qml.Interferometer(np.eye(4), wires=[1, 3
                                                  ]), 3, "Interferometer(M0)"),
            (qml.CatState(3.14, 2.14, 1,
                          wires=[1]), 1, "CatState(3.14, 2.14, 1)"),
            (qml.CoherentState(3.14, 2.14,
                               wires=[1]), 1, "CoherentState(3.14, 2.14)"),
            (
                qml.FockDensityMatrix(np.kron(np.eye(4), np.eye(4)),
                                      wires=[1, 2]),
                1,
                "FockDensityMatrix(M0)",
            ),
            (
                qml.FockDensityMatrix(np.kron(np.eye(4), np.eye(4)),
                                      wires=[1, 2]),
                2,
                "FockDensityMatrix(M0)",
            ),
            (
                qml.DisplacedSqueezedState(3.14, 2.14, 1.14, 0.14, wires=[1]),
                1,
                "DisplacedSqueezedState(3.14, 2.14, 1.14, 0.14)",
            ),
            (qml.FockState(7, wires=[1]), 1, "|7>"),
            (qml.FockStateVector(np.array([4, 5, 7]), wires=[1, 2, 3
                                                             ]), 1, "|4>"),
            (qml.FockStateVector(np.array([4, 5, 7]), wires=[1, 2, 3
                                                             ]), 2, "|5>"),
            (qml.FockStateVector(np.array([4, 5, 7]), wires=[1, 2, 3
                                                             ]), 3, "|7>"),
            (qml.SqueezedState(3.14, 2.14,
                               wires=[1]), 1, "SqueezedState(3.14, 2.14)"),
            (qml.Hermitian(np.eye(4), wires=[1, 2]), 1, "H0"),
            (qml.Hermitian(np.eye(4), wires=[1, 2]), 2, "H0"),
            (qml.X(wires=[1]), 1, "x"),
            (qml.P(wires=[1]), 1, "p"),
            (qml.FockStateProjector(np.array([4, 5, 7]),
                                    wires=[1, 2, 3]), 1, "|4,5,7X4,5,7|"),
            (
                qml.PolyXP(np.array([1, 2, 0, -1.3, 6]), wires=[1]),
                2,
                "1+2x_0-1.3x_1+6p_1",
            ),
            (
                qml.PolyXP(np.array([[1.2, 2.3, 4.5], [-1.2, 1.2, -1.5],
                                     [-1.3, 4.5, 2.3]]),
                           wires=[1]),
                1,
                "1.2+1.1x_0+3.2p_0+1.2x_0^2+2.3p_0^2+3x_0p_0",
            ),
            (
                qml.PolyXP(
                    np.array([
                        [1.2, 2.3, 4.5, 0, 0],
                        [-1.2, 1.2, -1.5, 0, 0],
                        [-1.3, 4.5, 2.3, 0, 0],
                        [0, 2.6, 0, 0, 0],
                        [0, 0, 0, -4.7, 0],
                    ]),
                    wires=[1],
                ),
                1,
                "1.2+1.1x_0+3.2p_0+1.2x_0^2+2.3p_0^2+3x_0p_0+2.6x_0x_1-4.7x_1p_1",
            ),
            (qml.QuadOperator(3.14, wires=[1]), 1, "cos(3.14)x+sin(3.14)p"),
        ],
    )
    def test_operator_representation_ascii(self, ascii_representation_resolver,
                                           op, wire, target):
        """Test that an Operator instance is properly resolved."""
        assert ascii_representation_resolver.operator_representation(
            op, wire) == target

    @pytest.mark.parametrize(
        "obs,wire,target",
        [
            (qml.expval(qml.PauliX(wires=[1])), 1, "⟨X⟩"),
            (qml.expval(qml.PauliY(wires=[1])), 1, "⟨Y⟩"),
            (qml.expval(qml.PauliZ(wires=[1])), 1, "⟨Z⟩"),
            (qml.expval(qml.Hadamard(wires=[1])), 1, "⟨H⟩"),
            (qml.expval(qml.Hermitian(np.eye(4), wires=[1, 2])), 1, "⟨H0⟩"),
            (qml.expval(qml.Hermitian(np.eye(4), wires=[1, 2])), 2, "⟨H0⟩"),
            (qml.expval(qml.NumberOperator(wires=[1])), 1, "⟨n⟩"),
            (qml.expval(qml.X(wires=[1])), 1, "⟨x⟩"),
            (qml.expval(qml.P(wires=[1])), 1, "⟨p⟩"),
            (
                qml.expval(
                    qml.FockStateProjector(np.array([4, 5, 7]),
                                           wires=[1, 2, 3])),
                1,
                "⟨|4,5,7╳4,5,7|⟩",
            ),
            (
                qml.expval(qml.PolyXP(np.array([1, 2, 0, -1.3, 6]), wires=[1
                                                                           ])),
                2,
                "⟨1+2x₀-1.3x₁+6p₁⟩",
            ),
            (
                qml.expval(
                    qml.PolyXP(np.array([[1.2, 2.3, 4.5], [-1.2, 1.2, -1.5],
                                         [-1.3, 4.5, 2.3]]),
                               wires=[1])),
                1,
                "⟨1.2+1.1x₀+3.2p₀+1.2x₀²+2.3p₀²+3x₀p₀⟩",
            ),
            (qml.expval(qml.QuadOperator(
                3.14, wires=[1])), 1, "⟨cos(3.14)x+sin(3.14)p⟩"),
            (qml.var(qml.PauliX(wires=[1])), 1, "Var[X]"),
            (qml.var(qml.PauliY(wires=[1])), 1, "Var[Y]"),
            (qml.var(qml.PauliZ(wires=[1])), 1, "Var[Z]"),
            (qml.var(qml.Hadamard(wires=[1])), 1, "Var[H]"),
            (qml.var(qml.Hermitian(np.eye(4), wires=[1, 2])), 1, "Var[H0]"),
            (qml.var(qml.Hermitian(np.eye(4), wires=[1, 2])), 2, "Var[H0]"),
            (qml.var(qml.NumberOperator(wires=[1])), 1, "Var[n]"),
            (qml.var(qml.X(wires=[1])), 1, "Var[x]"),
            (qml.var(qml.P(wires=[1])), 1, "Var[p]"),
            (
                qml.var(
                    qml.FockStateProjector(np.array([4, 5, 7]),
                                           wires=[1, 2, 3])),
                1,
                "Var[|4,5,7╳4,5,7|]",
            ),
            (
                qml.var(qml.PolyXP(np.array([1, 2, 0, -1.3, 6]), wires=[1])),
                2,
                "Var[1+2x₀-1.3x₁+6p₁]",
            ),
            (
                qml.var(
                    qml.PolyXP(np.array([[1.2, 2.3, 4.5], [-1.2, 1.2, -1.5],
                                         [-1.3, 4.5, 2.3]]),
                               wires=[1])),
                1,
                "Var[1.2+1.1x₀+3.2p₀+1.2x₀²+2.3p₀²+3x₀p₀]",
            ),
            (qml.var(qml.QuadOperator(
                3.14, wires=[1])), 1, "Var[cos(3.14)x+sin(3.14)p]"),
            (qml.sample(qml.PauliX(wires=[1])), 1, "Sample[X]"),
            (qml.sample(qml.PauliY(wires=[1])), 1, "Sample[Y]"),
            (qml.sample(qml.PauliZ(wires=[1])), 1, "Sample[Z]"),
            (qml.sample(qml.Hadamard(wires=[1])), 1, "Sample[H]"),
            (qml.sample(qml.Hermitian(np.eye(4), wires=[1, 2
                                                        ])), 1, "Sample[H0]"),
            (qml.sample(qml.Hermitian(np.eye(4), wires=[1, 2
                                                        ])), 2, "Sample[H0]"),
            (qml.sample(qml.NumberOperator(wires=[1])), 1, "Sample[n]"),
            (qml.sample(qml.X(wires=[1])), 1, "Sample[x]"),
            (qml.sample(qml.P(wires=[1])), 1, "Sample[p]"),
            (
                qml.sample(
                    qml.FockStateProjector(np.array([4, 5, 7]),
                                           wires=[1, 2, 3])),
                1,
                "Sample[|4,5,7╳4,5,7|]",
            ),
            (
                qml.sample(qml.PolyXP(np.array([1, 2, 0, -1.3, 6]), wires=[1
                                                                           ])),
                2,
                "Sample[1+2x₀-1.3x₁+6p₁]",
            ),
            (
                qml.sample(
                    qml.PolyXP(np.array([[1.2, 2.3, 4.5], [-1.2, 1.2, -1.5],
                                         [-1.3, 4.5, 2.3]]),
                               wires=[1])),
                1,
                "Sample[1.2+1.1x₀+3.2p₀+1.2x₀²+2.3p₀²+3x₀p₀]",
            ),
            (qml.sample(qml.QuadOperator(
                3.14, wires=[1])), 1, "Sample[cos(3.14)x+sin(3.14)p]"),
            (
                qml.expval(
                    qml.PauliX(wires=[1]) @ qml.PauliY(wires=[2])
                    @ qml.PauliZ(wires=[3])),
                1,
                "⟨X ⊗ Y ⊗ Z⟩",
            ),
            (
                qml.expval(
                    qml.FockStateProjector(np.array([4, 5, 7]),
                                           wires=[1, 2, 3])
                    @ qml.X(wires=[4])),
                1,
                "⟨|4,5,7╳4,5,7| ⊗ x⟩",
            ),
            (
                qml.expval(
                    qml.FockStateProjector(np.array([4, 5, 7]),
                                           wires=[1, 2, 3])
                    @ qml.X(wires=[4])),
                2,
                "⟨|4,5,7╳4,5,7| ⊗ x⟩",
            ),
            (
                qml.expval(
                    qml.FockStateProjector(np.array([4, 5, 7]),
                                           wires=[1, 2, 3])
                    @ qml.X(wires=[4])),
                3,
                "⟨|4,5,7╳4,5,7| ⊗ x⟩",
            ),
            (
                qml.expval(
                    qml.FockStateProjector(np.array([4, 5, 7]),
                                           wires=[1, 2, 3])
                    @ qml.X(wires=[4])),
                4,
                "⟨|4,5,7╳4,5,7| ⊗ x⟩",
            ),
            (
                qml.sample(
                    qml.Hermitian(np.eye(4), wires=[1, 2]) @ qml.Hermitian(
                        np.eye(4), wires=[0, 3])),
                0,
                "Sample[H0 ⊗ H0]",
            ),
            (
                qml.sample(
                    qml.Hermitian(np.eye(4), wires=[1, 2]) @ qml.Hermitian(
                        2 * np.eye(4), wires=[0, 3])),
                0,
                "Sample[H0 ⊗ H1]",
            ),
        ],
    )
    def test_output_representation_unicode(self,
                                           unicode_representation_resolver,
                                           obs, wire, target):
        """Test that an Observable instance with return type is properly resolved."""
        assert unicode_representation_resolver.output_representation(
            obs, wire) == target

    def test_fallback_output_representation_unicode(
            self, unicode_representation_resolver):
        """Test that an Observable instance with return type is properly resolved."""
        obs = qml.PauliZ(0)
        obs.return_type = "TestReturnType"

        assert unicode_representation_resolver.output_representation(
            obs, 0) == "TestReturnType[Z]"

    @pytest.mark.parametrize(
        "obs,wire,target",
        [
            (qml.expval(qml.PauliX(wires=[1])), 1, "<X>"),
            (qml.expval(qml.PauliY(wires=[1])), 1, "<Y>"),
            (qml.expval(qml.PauliZ(wires=[1])), 1, "<Z>"),
            (qml.expval(qml.Hadamard(wires=[1])), 1, "<H>"),
            (qml.expval(qml.Hermitian(np.eye(4), wires=[1, 2])), 1, "<H0>"),
            (qml.expval(qml.Hermitian(np.eye(4), wires=[1, 2])), 2, "<H0>"),
            (qml.expval(qml.NumberOperator(wires=[1])), 1, "<n>"),
            (qml.expval(qml.X(wires=[1])), 1, "<x>"),
            (qml.expval(qml.P(wires=[1])), 1, "<p>"),
            (
                qml.expval(
                    qml.FockStateProjector(np.array([4, 5, 7]),
                                           wires=[1, 2, 3])),
                1,
                "<|4,5,7X4,5,7|>",
            ),
            (
                qml.expval(qml.PolyXP(np.array([1, 2, 0, -1.3, 6]), wires=[1
                                                                           ])),
                2,
                "<1+2x_0-1.3x_1+6p_1>",
            ),
            (
                qml.expval(
                    qml.PolyXP(np.array([[1.2, 2.3, 4.5], [-1.2, 1.2, -1.5],
                                         [-1.3, 4.5, 2.3]]),
                               wires=[1])),
                1,
                "<1.2+1.1x_0+3.2p_0+1.2x_0^2+2.3p_0^2+3x_0p_0>",
            ),
            (qml.expval(qml.QuadOperator(
                3.14, wires=[1])), 1, "<cos(3.14)x+sin(3.14)p>"),
            (qml.var(qml.PauliX(wires=[1])), 1, "Var[X]"),
            (qml.var(qml.PauliY(wires=[1])), 1, "Var[Y]"),
            (qml.var(qml.PauliZ(wires=[1])), 1, "Var[Z]"),
            (qml.var(qml.Hadamard(wires=[1])), 1, "Var[H]"),
            (qml.var(qml.Hermitian(np.eye(4), wires=[1, 2])), 1, "Var[H0]"),
            (qml.var(qml.Hermitian(np.eye(4), wires=[1, 2])), 2, "Var[H0]"),
            (qml.var(qml.NumberOperator(wires=[1])), 1, "Var[n]"),
            (qml.var(qml.X(wires=[1])), 1, "Var[x]"),
            (qml.var(qml.P(wires=[1])), 1, "Var[p]"),
            (
                qml.var(
                    qml.FockStateProjector(np.array([4, 5, 7]),
                                           wires=[1, 2, 3])),
                1,
                "Var[|4,5,7X4,5,7|]",
            ),
            (
                qml.var(qml.PolyXP(np.array([1, 2, 0, -1.3, 6]), wires=[1])),
                2,
                "Var[1+2x_0-1.3x_1+6p_1]",
            ),
            (
                qml.var(
                    qml.PolyXP(np.array([[1.2, 2.3, 4.5], [-1.2, 1.2, -1.5],
                                         [-1.3, 4.5, 2.3]]),
                               wires=[1])),
                1,
                "Var[1.2+1.1x_0+3.2p_0+1.2x_0^2+2.3p_0^2+3x_0p_0]",
            ),
            (qml.var(qml.QuadOperator(
                3.14, wires=[1])), 1, "Var[cos(3.14)x+sin(3.14)p]"),
            (qml.sample(qml.PauliX(wires=[1])), 1, "Sample[X]"),
            (qml.sample(qml.PauliY(wires=[1])), 1, "Sample[Y]"),
            (qml.sample(qml.PauliZ(wires=[1])), 1, "Sample[Z]"),
            (qml.sample(qml.Hadamard(wires=[1])), 1, "Sample[H]"),
            (qml.sample(qml.Hermitian(np.eye(4), wires=[1, 2
                                                        ])), 1, "Sample[H0]"),
            (qml.sample(qml.Hermitian(np.eye(4), wires=[1, 2
                                                        ])), 2, "Sample[H0]"),
            (qml.sample(qml.NumberOperator(wires=[1])), 1, "Sample[n]"),
            (qml.sample(qml.X(wires=[1])), 1, "Sample[x]"),
            (qml.sample(qml.P(wires=[1])), 1, "Sample[p]"),
            (
                qml.sample(
                    qml.FockStateProjector(np.array([4, 5, 7]),
                                           wires=[1, 2, 3])),
                1,
                "Sample[|4,5,7X4,5,7|]",
            ),
            (
                qml.sample(qml.PolyXP(np.array([1, 2, 0, -1.3, 6]), wires=[1
                                                                           ])),
                2,
                "Sample[1+2x_0-1.3x_1+6p_1]",
            ),
            (
                qml.sample(
                    qml.PolyXP(np.array([[1.2, 2.3, 4.5], [-1.2, 1.2, -1.5],
                                         [-1.3, 4.5, 2.3]]),
                               wires=[1])),
                1,
                "Sample[1.2+1.1x_0+3.2p_0+1.2x_0^2+2.3p_0^2+3x_0p_0]",
            ),
            (qml.sample(qml.QuadOperator(
                3.14, wires=[1])), 1, "Sample[cos(3.14)x+sin(3.14)p]"),
            (
                qml.expval(
                    qml.PauliX(wires=[1]) @ qml.PauliY(wires=[2])
                    @ qml.PauliZ(wires=[3])),
                1,
                "<X @ Y @ Z>",
            ),
            (
                qml.expval(
                    qml.FockStateProjector(np.array([4, 5, 7]),
                                           wires=[1, 2, 3])
                    @ qml.X(wires=[4])),
                1,
                "<|4,5,7X4,5,7| @ x>",
            ),
            (
                qml.expval(
                    qml.FockStateProjector(np.array([4, 5, 7]),
                                           wires=[1, 2, 3])
                    @ qml.X(wires=[4])),
                2,
                "<|4,5,7X4,5,7| @ x>",
            ),
            (
                qml.expval(
                    qml.FockStateProjector(np.array([4, 5, 7]),
                                           wires=[1, 2, 3])
                    @ qml.X(wires=[4])),
                3,
                "<|4,5,7X4,5,7| @ x>",
            ),
            (
                qml.expval(
                    qml.FockStateProjector(np.array([4, 5, 7]),
                                           wires=[1, 2, 3])
                    @ qml.X(wires=[4])),
                4,
                "<|4,5,7X4,5,7| @ x>",
            ),
            (
                qml.sample(
                    qml.Hermitian(np.eye(4), wires=[1, 2]) @ qml.Hermitian(
                        np.eye(4), wires=[0, 3])),
                0,
                "Sample[H0 @ H0]",
            ),
            (
                qml.sample(
                    qml.Hermitian(np.eye(4), wires=[1, 2]) @ qml.Hermitian(
                        2 * np.eye(4), wires=[0, 3])),
                0,
                "Sample[H0 @ H1]",
            ),
        ],
    )
    def test_output_representation_ascii(self, ascii_representation_resolver,
                                         obs, wire, target):
        """Test that an Observable instance with return type is properly resolved."""
        assert ascii_representation_resolver.output_representation(
            obs, wire) == target

    def test_element_representation_none(self,
                                         unicode_representation_resolver):
        """Test that element_representation properly handles None."""
        assert unicode_representation_resolver.element_representation(None,
                                                                      0) == ""

    def test_element_representation_str(self, unicode_representation_resolver):
        """Test that element_representation properly handles strings."""
        assert unicode_representation_resolver.element_representation(
            "Test", 0) == "Test"

    def test_element_representation_calls_output(
            self, unicode_representation_resolver):
        """Test that element_representation calls output_representation for returned observables."""

        unicode_representation_resolver.output_representation = Mock()

        obs = qml.sample(qml.PauliX(3))
        wire = 3

        unicode_representation_resolver.element_representation(obs, wire)

        assert unicode_representation_resolver.output_representation.call_args[
            0] == (obs, wire)

    def test_element_representation_calls_operator(
            self, unicode_representation_resolver):
        """Test that element_representation calls operator_representation for all operators that are not returned."""

        unicode_representation_resolver.operator_representation = Mock()

        op = qml.PauliX(3)
        wire = 3

        unicode_representation_resolver.element_representation(op, wire)

        assert unicode_representation_resolver.operator_representation.call_args[
            0] == (op, wire)
Exemple #20
0
 def circuit(x, y):
     qml.Squeezing(x, 0, wires=0)
     qml.Squeezing(y, 0, wires=1)
     return qml.expval(qml.Identity(wires=[0]))
Exemple #21
0
 def circuit():
     qml.templates.Permute(permutation, wires=range(4))
     return qml.expval(qml.Identity(0))
Exemple #22
0
 def circuit(a):
     qml.Displacement(a, 0, wires=0)
     return qml.expval(qml.Identity(0))
Exemple #23
0
 def circuit():
     return qml.expval(qml.Identity(wires=0) @ qml.Identity(wires=1))
Exemple #24
0
 def circuit():
     qml.apply(ops[operation])
     return qml.expval(qml.Identity(wires=0))
Exemple #25
0
 def circuit(*inp_):
     template(*inp_, wires=range(2))
     return qml.expval(qml.Identity(0))
Exemple #26
0
 def circuit():
     ops[operation].queue().inv()
     return qml.expval(qml.Identity(wires=0))
Exemple #27
0
        @qml.qnode(dev)
        def f():
            qml.QubitStateVector(rnd_state, wires=range(n_all_wires))
            qml.MultiControlledX(control_wires=control_wires,
                                 wires=target_wire).inv()
            for op in tape.operations:
                op.queue()
            return qml.state()

        assert np.allclose(f(), rnd_state)
        spy.assert_called()


label_data = [
    (qml.Identity(0), "I", "I"),
    (qml.Hadamard(0), "H", "H"),
    (qml.PauliX(0), "X", "X"),
    (qml.PauliY(0), "Y", "Y"),
    (qml.PauliZ(0), "Z", "Z"),
    (qml.S(wires=0), "S", "S⁻¹"),
    (qml.T(wires=0), "T", "T⁻¹"),
    (qml.SX(wires=0), "SX", "SX⁻¹"),
    (qml.CNOT(wires=(0, 1)), "⊕", "⊕"),
    (qml.CZ(wires=(0, 1)), "Z", "Z"),
    (qml.CY(wires=(0, 1)), "Y", "Y"),
    (qml.SWAP(wires=(0, 1)), "SWAP", "SWAP⁻¹"),
    (qml.ISWAP(wires=(0, 1)), "ISWAP", "ISWAP⁻¹"),
    (qml.SISWAP(wires=(0, 1)), "SISWAP", "SISWAP⁻¹"),
    (qml.SQISW(wires=(0, 1)), "SISWAP", "SISWAP⁻¹"),
    (qml.CSWAP(wires=(0, 1, 2)), "SWAP", "SWAP"),
Exemple #28
0
 def circuit():
     template(*args, **kwargs)
     return qml.expval(qml.Identity(0))
Exemple #29
0
 def circuit():
     qml.RX(theta, wires=[0])
     qml.RX(phi, wires=[1])
     qml.CNOT(wires=[0, 1])
     return qml.expval(qml.Identity(wires=0)), qml.expval(qml.Identity(wires=1))
Exemple #30
0
 def circuit2():
     qml.templates.ArbitraryStatePreparation(weights,
                                             wires=["z", "a", "k"])
     return qml.expval(qml.Identity("z"))