def expand(self):

        nm_wires = [
            self.wires[l:l + 2] for l in range(0,
                                               len(self.wires) - 1, 2)
        ]
        nm_wires += [
            self.wires[l:l + 2] for l in range(1,
                                               len(self.wires) - 1, 2)
        ]

        with qml.tape.QuantumTape() as tape:

            qml.BasisState(self.init_state, wires=self.wires)

            for l in range(self.n_layers):
                for i, wires_ in enumerate(nm_wires):
                    u1_ex_gate(self.parameters[0][l, i, 0],
                               self.parameters[0][l, i, 1],
                               wires=wires_)
        return tape
Example #2
0
    def circuit(self, a, b):
        aBasis = i_to_basis(a, pad=self.reg_a_size)
        bBasis = i_to_basis(b, pad=self.reg_a_size)
        zeros = [0] * (self.reg_b_size - self.reg_a_size)
        ancilla = [0] * (self.ancilla_size)
        qml.BasisState(np.array(aBasis + zeros + bBasis + ancilla),
                       wires=range(self.reg_a_size + self.reg_b_size +
                                   self.ancilla_size))

        for g in self.gateSet:
            if len(g) == 1:
                qml.PauliX(g[0])
            if len(g) == 2:
                qml.CNOT(wires=list(g))
            if len(g) == 3:
                qml.Toffoli(wires=list(g))

        return [
            qml.expval(qml.PauliZ(i))
            for i in range(self.reg_a_size + self.reg_b_size)
        ]
Example #3
0
    def test_casting(self):
        """Test that copying and casting works as expected"""
        with QuantumTape() as tape:
            qml.BasisState(np.array([1, 0]), wires=[0, 1])
            qml.RY(0.5, wires=[1])
            qml.CNOT(wires=[0, 1])
            qml.expval(qml.PauliZ(0) @ qml.PauliY(1))

        # copy and cast to a JacobianTape
        copied_tape = tape.copy(tape_cls=qml.tape.tapes.JacobianTape)

        # check that the copying worked
        assert copied_tape is not tape
        assert copied_tape.operations == tape.operations
        assert copied_tape.observables == tape.observables
        assert copied_tape.measurements == tape.measurements
        assert copied_tape.operations[0] is tape.operations[0]

        # check that the casting worked
        assert isinstance(copied_tape, qml.tape.tapes.JacobianTape)
        assert not isinstance(tape, qml.tape.tapes.JacobianTape)
Example #4
0
def variational_ansatz_zero(params, wires):
    """
    DO NOT MODIFY anything in this function! It is used to judge your solution.

    This is ansatz is used to help with the problem structure. It applies
    alternating layers of rotations and CNOTs.

    Don't worry about the contents of this function for now—you'll be designing
    your own ansatze in a later problem.

    Args:
        params (np.ndarray): An array of floating-point numbers with size (n, 3),
            where n is the number of parameter sets required (this is determined by
            the problem Hamiltonian).
        wires (qml.Wires): The device wires this circuit will run on.
    """
    n_qubits = len(wires)
    n_rotations = len(params)

    if n_rotations > 1:
        n_layers = n_rotations // n_qubits
        n_extra_rots = n_rotations - n_layers * n_qubits
 
        # Alternating layers of unitary rotations on every qubit followed by a
        # ring cascade of CNOTs.

        qml.BasisState(np.array([0 for i in range(n_qubits)]), wires=[i for i in range(n_qubits)])
        for layer_idx in range(n_layers):
            layer_params = params[layer_idx * n_qubits : layer_idx * n_qubits + n_qubits, :]
            qml.broadcast(qml.Rot, wires, pattern="single", parameters=layer_params)
            qml.broadcast(qml.CNOT, wires, pattern="ring")

        # There may be "extra" parameter sets required for which it's not necessarily
        # to perform another full alternating cycle. Apply these to the qubits as needed.
        extra_params = params[-n_extra_rots:, :]
        extra_wires = wires[: n_qubits - 1 - n_extra_rots : -1]
        qml.broadcast(qml.Rot, extra_wires, pattern="single", parameters=extra_params)
    else:
        # For 1-qubit case, just a single rotation to the qubit
        qml.Rot(*params[0], wires=wires[0])
    def test_skips_prep_circuit(self):
        """Test expected serialization for a simple circuit with state preparation, such that
        the state preparation is skipped"""
        with qml.tape.QuantumTape() as tape:
            qml.QubitStateVector([1, 0], wires=0)
            qml.BasisState([1], wires=1)
            qml.RX(0.4, wires=0)
            qml.RY(0.6, wires=1)
            qml.CNOT(wires=[0, 1])

        s = _serialize_ops(tape, self.wires_dict)
        s_expected = (
            (
                ["RX", "RY", "CNOT"],
                [[0.4], [0.6], []],
                [[0], [1], [0, 1]],
                [False, False, False],
                [[], [], []],
            ),
            True,
        )
        assert s == s_expected
Example #6
0
    def test_shallow_copy_with_operations(self, copy_fn):
        """Test that shallow copying of a tape and operations allows
        parameters to be set independently"""

        with QuantumTape() as tape:
            qml.BasisState(np.array([1, 0]), wires=[0, 1])
            qml.RY(0.5, wires=[1])
            qml.CNOT(wires=[0, 1])
            qml.expval(qml.PauliZ(0) @ qml.PauliY(1))

        copied_tape = copy_fn(tape)

        assert copied_tape is not tape

        # the operations are not references; they are unique objects
        assert copied_tape.operations != tape.operations
        assert copied_tape.observables != tape.observables
        assert copied_tape.measurements != tape.measurements
        assert copied_tape.operations[0] is not tape.operations[0]

        # however, the underlying operation data *is still shared*
        assert copied_tape.operations[0].wires is tape.operations[0].wires
        assert copied_tape.operations[0].data[0] is tape.operations[0].data[0]

        assert tape.get_parameters() == copied_tape.get_parameters()
        assert tape.wires == copied_tape.wires
        assert tape.data == copied_tape.data

        # Since they have unique operations, mutating the parameters
        # on one tape will *not* affect the parameters on another tape
        new_params = [np.array([0, 0]), 0.2]
        tape.set_parameters(new_params)

        for i, j in zip(tape.get_parameters(), new_params):
            assert i is j

        for i, j in zip(copied_tape.get_parameters(), new_params):
            assert not np.all(i == j)
            assert i is not j
Example #7
0
    def test_shallow_copy(self):
        """Test that shallow copying of a tape results in all
        contained data being shared between the original tape and the copy"""
        with QuantumTape() as tape:
            qml.BasisState(np.array([1, 0]), wires=[0, 1])
            qml.RY(0.5, wires=[1])
            qml.CNOT(wires=[0, 1])
            qml.expval(qml.PauliZ(0) @ qml.PauliY(1))

        copied_tape = tape.copy()

        assert copied_tape is not tape

        # the operations are simply references
        assert copied_tape.operations == tape.operations
        assert copied_tape.observables == tape.observables
        assert copied_tape.measurements == tape.measurements
        assert copied_tape.operations[0] is tape.operations[0]

        # operation data is also a reference
        assert copied_tape.operations[0].wires is tape.operations[0].wires
        assert copied_tape.operations[0].data[0] is tape.operations[0].data[0]

        # check that all tape metadata is identical
        assert tape.get_parameters() == copied_tape.get_parameters()
        assert tape.wires == copied_tape.wires
        assert tape.data == copied_tape.data

        # since the copy is shallow, mutating the parameters
        # on one tape will affect the parameters on another tape
        new_params = [np.array([0, 0]), 0.2]
        tape.set_parameters(new_params)

        # check that they are the same objects in memory
        for i, j in zip(tape.get_parameters(), new_params):
            assert i is j

        for i, j in zip(copied_tape.get_parameters(), new_params):
            assert i is j
Example #8
0
    def test_inverse(self):
        """Test that inversion works as expected"""
        init_state = np.array([1, 1])
        p = [0.1, 0.2, 0.3, 0.4]

        with QuantumTape() as tape:
            prep = qml.BasisState(init_state, wires=[0, "a"])
            ops = [qml.RX(p[0], wires=0), qml.Rot(*p[1:], wires=0).inv(), qml.CNOT(wires=[0, "a"])]
            m1 = qml.probs(wires=0)
            m2 = qml.probs(wires="a")

        tape.inv()

        # check that operation order is reversed
        assert tape.operations == [prep] + ops[::-1]

        # check that operations are inverted
        assert ops[0].inverse
        assert not ops[1].inverse
        assert ops[2].inverse

        # check that parameter order has reversed
        assert tape.get_parameters() == [init_state, p[1], p[2], p[3], p[0]]
Example #9
0
    def test_parameter_transforms(self):
        """Test that inversion correctly changes trainable parameters"""
        init_state = np.array([1, 1])
        p = [0.1, 0.2, 0.3, 0.4]

        with QuantumTape() as tape:
            prep = qml.BasisState(init_state, wires=[0, "a"])
            ops = [qml.RX(p[0], wires=0), qml.Rot(*p[1:], wires=0).inv(), qml.CNOT(wires=[0, "a"])]
            m1 = qml.probs(wires=0)
            m2 = qml.probs(wires="a")

        tape.trainable_params = {1, 2}
        tape.inv()

        # check that operation order is reversed
        assert tape.trainable_params == {1, 4}
        assert tape.get_parameters() == [p[1], p[0]]

        # undo the inverse
        tape.inv()
        assert tape.trainable_params == {1, 2}
        assert tape.get_parameters() == [p[0], p[1]]
        assert tape._ops == ops
Example #10
0
def circuit_decomposed(weights):
    wires = range(4)
    qwires = [
        wires[i:i + 4] for i in range(0, len(wires), 4)
        if len(wires[i:i + 4]) == 4
    ]
    if len(wires) > 4:
        qwires += [
            wires[i:i + 4] for i in range(2, len(wires), 4)
            if len(wires[i:i + 4]) == 4
        ]
    qml.BasisState(qml.math.array([1, 1, 0, 0]), wires=wires)
    include_pi_param = qml.math.array(np.pi,
                                      like=qml.math._multi_dispatch(weights))
    for layer in range(weights.shape[0]):
        for idx in range(weights.shape[1]):
            qml.OrbitalRotation.decomposition(include_pi_param,
                                              wires=qwires[idx])
            qml.DoubleExcitation.decomposition(weights[layer][idx][0],
                                               wires=qwires[idx])
            qml.OrbitalRotation.decomposition(weights[layer][idx][1],
                                              wires=qwires[idx])

    return qml.expval(qml.PauliZ(0))
Example #11
0
    def test_deep_copy(self):
        """Test that deep copying a tape works, and copies all constituent data except parameters"""
        with QuantumTape() as tape:
            qml.BasisState(np.array([1, 0]), wires=[0, 1])
            qml.RY(0.5, wires=[1])
            qml.CNOT(wires=[0, 1])
            qml.expval(qml.PauliZ(0) @ qml.PauliY(1))

        copied_tape = copy.deepcopy(tape)

        assert copied_tape is not tape

        # the operations are not references
        assert copied_tape.operations != tape.operations
        assert copied_tape.observables != tape.observables
        assert copied_tape.measurements != tape.measurements
        assert copied_tape.operations[0] is not tape.operations[0]

        # The underlying operation data has also been copied
        assert copied_tape.operations[0].wires is not tape.operations[0].wires

        # however, the underlying operation *parameters* are still shared
        # to support PyTorch, which does not support deep copying of tensors
        assert copied_tape.operations[0].data[0] is tape.operations[0].data[0]
Example #12
0
 def circuit():
     """A combination of two and three qubit gates with the one_qubit_block and a simple
     PauliZ measurement applied to an input basis state"""
     qml.BasisState(np.array(basis_state), wires=[0, 1, 2])
     qml.RX(0.5, wires=0)
     qml.Hadamard(wires=1)
     qml.RY(0.9, wires=2)
     qml.CNOT(wires=[0, 1])
     qml.CNOT(wires=[2, 0])
     qml.CZ(wires=[1, 0])
     one_qubit_block(wires=0)
     qml.Toffoli(wires=[1, 0, 2])
     one_qubit_block(wires=2)
     qml.SWAP(wires=[0, 1])
     qml.SWAP(wires=[0, 2])
     qml.CRX(0.5, wires=[1, 0])
     qml.CSWAP(wires=[2, 1, 0])
     qml.CRY(0.9, wires=[2, 1])
     one_qubit_block(wires=1)
     qml.CRZ(0.02, wires=[0, 1])
     qml.CRot(0.2, 0.3, 0.7, wires=[2, 1])
     qml.RZ(0.4, wires=0)
     qml.Toffoli(wires=[2, 1, 0])
     return qml.expval(qml.PauliZ(0))
def statepreparation(x):
    qml.BasisState(x, wires=[0, 1, 2, 3])
Example #14
0
 def circuit():
     qml.BasisState(basis_state, wires=range(n_wires))
     return qml.probs(wires=range(n_wires))
Example #15
0
import numpy as np
import pennylane as qml

from scipy.linalg import block_diag
from flaky import flaky

pytestmark = pytest.mark.skip_unsupported

np.random.seed(42)

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

# gates for which device support is tested
ops = {
    "BasisState": qml.BasisState(np.array([0]), wires=[0]),
    "CNOT": qml.CNOT(wires=[0, 1]),
    "CRX": qml.CRX(0, wires=[0, 1]),
    "CRY": qml.CRY(0, wires=[0, 1]),
    "CRZ": qml.CRZ(0, wires=[0, 1]),
    "CRot": qml.CRot(0, 0, 0, wires=[0, 1]),
    "CSWAP": qml.CSWAP(wires=[0, 1, 2]),
    "CZ": qml.CZ(wires=[0, 1]),
    "CY": qml.CY(wires=[0, 1]),
    "DiagonalQubitUnitary": qml.DiagonalQubitUnitary(np.array([1, 1]), wires=[0]),
    "Hadamard": qml.Hadamard(wires=[0]),
    "MultiRZ": qml.MultiRZ(0, wires=[0]),
    "PauliX": qml.PauliX(wires=[0]),
    "PauliY": qml.PauliY(wires=[0]),
    "PauliZ": qml.PauliZ(wires=[0]),
    "PhaseShift": qml.PhaseShift(0, wires=[0]),
 def circuit():
     qml.BasisState(np.array(par), wires=wires)
     return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1))
Example #17
0
 def circuit(x, y, z):
     """Reference QNode"""
     qml.BasisState(np.array([1]), wires=0)
     qml.Hadamard(wires=0)
     qml.Rot(x, y, z, wires=0)
     return qml.expval(qml.PauliZ(0))
Example #18
0
def ParticleConservingU2(weights, wires, init_state=None):
    r"""Implements the heuristic VQE ansatz for Quantum Chemistry simulations using the
    particle-conserving entangler :math:`U_\mathrm{ent}(\vec{\theta}, \vec{\phi})` proposed in
    `arXiv:1805.04340 <https://arxiv.org/abs/1805.04340>`_.

    This template prepares :math:`N`-qubit trial states by applying :math:`D` layers of the entangler
    block :math:`U_\mathrm{ent}(\vec{\theta}, \vec{\phi})` to the Hartree-Fock state

    .. math::

        \vert \Psi(\vec{\theta}, \vec{\phi}) \rangle = \hat{U}^{(D)}_\mathrm{ent}(\vec{\theta}_D,
        \vec{\phi}_D) \dots \hat{U}^{(2)}_\mathrm{ent}(\vec{\theta}_2, \vec{\phi}_2)
        \hat{U}^{(1)}_\mathrm{ent}(\vec{\theta}_1, \vec{\phi}_1) \vert \mathrm{HF}\rangle,

    where :math:`\hat{U}^{(i)}_\mathrm{ent}(\vec{\theta}_i, \vec{\phi}_i) =
    \hat{R}_\mathrm{z}(\vec{\theta}_i) \hat{U}_\mathrm{2,\mathrm{ex}}(\vec{\phi}_i)`.
    The circuit implementing the entangler blocks is shown in the figure below:

    |

    .. figure:: ../../_static/templates/layers/particle_conserving_u2.png
        :align: center
        :width: 60%
        :target: javascript:void(0);

    |

    Each layer contains :math:`N` rotation gates :math:`R_\mathrm{z}(\vec{\theta})` and
    :math:`N-1` particle-conserving exchange gates :math:`U_{2,\mathrm{ex}}(\phi)`
    that act on pairs of nearest-neighbors qubits. The repeated units across several qubits are
    shown in dotted boxes.  The unitary matrix representing :math:`U_{2,\mathrm{ex}}(\phi)`
    (`arXiv:1805.04340 <https://arxiv.org/abs/1805.04340>`_) is decomposed into its elementary
    gates and implemented in the :func:`~.u2_ex_gate` function using PennyLane quantum operations.

    |

    .. figure:: ../../_static/templates/layers/u2_decomposition.png
        :align: center
        :width: 60%
        :target: javascript:void(0);

    |


    Args:
        weights (tensor_like): Weight tensor of shape ``(D, M)`` where ``D`` is the number of
            layers and ``M`` = ``2N-1`` is the total number of rotation ``(N)`` and exchange
            ``(N-1)`` gates per layer.
        wires (Iterable or Wires): Wires that the template acts on. Accepts an iterable of numbers
            or strings, or a Wires object.
        init_state (tensor_like): shape ``(len(wires),)`` tensor representing the Hartree-Fock state
            used to initialize the wires.

    Raises:
        ValueError: if inputs do not have the correct format

    .. UsageDetails::


        #. The number of wires has to be equal to the number of spin orbitals included in
           the active space.

        #. The number of trainable parameters scales with the number of layers :math:`D` as
           :math:`D(2N-1)`.

        An example of how to use this template is shown below:

        .. code-block:: python

            import pennylane as qml
            from pennylane.templates import ParticleConservingU2

            from functools import partial

            # Build the electronic Hamiltonian from a local .xyz file
            h, qubits = qml.qchem.molecular_hamiltonian("h2", "h2.xyz")

            # Define the HF state
            ref_state = qml.qchem.hf_state(2, qubits)

            # Define the device
            dev = qml.device('default.qubit', wires=qubits)

            # Define the ansatz
            ansatz = partial(ParticleConservingU2, init_state=ref_state)

            # Define the cost function
            cost_fn = qml.ExpvalCost(ansatz, h, dev)

            # Compute the expectation value of 'h' for a given set of parameters
            layers = 1
            params = qml.init.particle_conserving_u2_normal(layers, qubits)
            print(cost_fn(params))
    """

    wires = Wires(wires)
    repeat, nm_wires, init_state = _preprocess(weights, wires, init_state)

    qml.BasisState(init_state, wires=wires)

    for l in range(repeat):

        for j, _ in enumerate(wires):
            RZ(weights[l, j], wires=wires[j])

        for i, wires_ in enumerate(nm_wires):
            u2_ex_gate(weights[l, len(wires) + i], wires=wires_)
Example #19
0
 def circuit(weights, x=None):
     qml.BasisState(x, wires=range(num_wires))
     StronglyEntanglingLayers(weights, wires=range(num_wires))
     return qml.expval(qml.PauliZ(0))
Example #20
0
 def qnode(state=None):
     qml.BasisState(state, wires=[0, 1, 2, 3])
     return qml.expval(qml.PauliZ(0))
Example #21
0
def circuit(param, wires):
    qml.BasisState(np.array([1, 1, 0, 0]), wires=[0, 1, 2, 3])
    qml.RY(param, wires=2)
    qml.CNOT(wires=[2, 3])
    qml.CNOT(wires=[2, 0])
    qml.CNOT(wires=[3, 1])
 def circuit(x):
     qml.BasisState(np.array([x, 0]), wires=[0, 1])  # not differentiable
     qml.RX(x, wires=[0])
     return qml.expval(qml.PauliZ(0))
Example #23
0
 def template(param):
     qml.BasisState(np.array([0, 0, 1, 1]), wires=list(range(4)))
     qml.RY(param, wires=[2])
     qml.CNOT(wires=[2, 3])
Example #24
0
 def circuit(x, y, input_state=np.array([0, 0])):
     qml.BasisState(input_state, wires=[0, 1])
     qml.RX(x, wires=[0])
     qml.RY(y, wires=[0])
     return qml.expval(qml.PauliZ(0))
 def circuit(x):
     qml.BasisState(x, wires=[1])
     return qml.expval(qml.PauliZ(0))
Example #26
0
def ParticleConservingU1(weights, wires, init_state=None):
    r"""Implements the heuristic VQE ansatz for quantum chemistry simulations using the
    particle-conserving gate :math:`U_{1,\mathrm{ex}}` proposed by Barkoutsos *et al.* in
    `arXiv:1805.04340 <https://arxiv.org/abs/1805.04340>`_.

    This template prepares :math:`N`-qubit trial states by applying :math:`D` layers of the
    entangler block :math:`U_\mathrm{ent}(\vec{\phi}, \vec{\theta})` to the Hartree-Fock
    state

    .. math::

        \vert \Psi(\vec{\phi}, \vec{\theta}) \rangle = \hat{U}^{(D)}_\mathrm{ent}(\vec{\phi}_D,
        \vec{\theta}_D) \dots \hat{U}^{(2)}_\mathrm{ent}(\vec{\phi}_2, \vec{\theta}_2)
        \hat{U}^{(1)}_\mathrm{ent}(\vec{\phi}_1, \vec{\theta}_1) \vert \mathrm{HF}\rangle.

    The circuit implementing the entangler blocks is shown in the figure below:

    |

    .. figure:: ../../_static/templates/layers/particle_conserving_u1.png
        :align: center
        :width: 50%
        :target: javascript:void(0);

    |

    The repeated units across several qubits are shown in dotted boxes. Each layer
    contains :math:`N-1` particle-conserving two-parameter exchange gates
    :math:`U_{1,\mathrm{ex}}(\phi, \theta)` that act on pairs of nearest neighbors qubits.
    The unitary matrix representing :math:`U_{1,\mathrm{ex}}(\phi, \theta)`
    is given by (see `arXiv:1805.04340 <https://arxiv.org/abs/1805.04340>`_),

    .. math::

        U_{1, \mathrm{ex}}(\phi, \theta) = \left(\begin{array}{cccc}
        1 & 0 & 0 & 0 \\
        0 & \mathrm{cos}(\theta) & e^{i\phi} \mathrm{sin}(\theta) & 0 \\
        0 & e^{-i\phi} \mathrm{sin}(\theta) & -\mathrm{cos}(\theta) & 0 \\
        0 & 0 & 0 & 1 \\
        \end{array}\right).

    The figure below shows the circuit decomposing :math:`U_{1, \mathrm{ex}}` in
    elementary gates. The Pauli matrix :math:`\sigma_z` and single-qubit rotation
    :math:`R(0, 2 \theta, 0)` apply the Pauli Z operator and an arbitrary rotation
    on the qubit ``n`` with qubit ``m`` bein the control qubit,

    |

    .. figure:: ../../_static/templates/layers/u1_decomposition.png
        :align: center
        :width: 80%
        :target: javascript:void(0);

    |

    :math:`U_A(\phi)` is the unitary matrix

    .. math::

        U_A(\phi) = \left(\begin{array}{cc} 0 & e^{-i\phi} \\ e^{-i\phi} & 0 \\ \end{array}\right),

    which is applied controlled on the state of qubit ``m`` and can be further decomposed in
    terms of the
    `quantum operations <https://pennylane.readthedocs.io/en/stable/introduction/operations.html>`_
    supported by Pennylane,

    |

    .. figure:: ../../_static/templates/layers/ua_decomposition.png
        :align: center
        :width: 70%
        :target: javascript:void(0);

    |

    where,

    |

    .. figure:: ../../_static/templates/layers/phaseshift_decomposition.png
        :align: center
        :width: 65%
        :target: javascript:void(0);

    |

    The quantum circuits above decomposing the unitaries :math:`U_{1,\mathrm{ex}}(\phi, \theta)`
    and :math:`U_A(\phi)` are implemented by the ``u1_ex_gate`` and ``decompose_ua``
    functions, respectively. :math:`R_\phi` refers to the ``PhaseShift`` gate in the
    circuit diagram.

    Args:
        weights (array[float]): Array of weights of shape ``(D, M, 2)``.
            ``D`` is the number of entangler block layers and :math:`M=N-1`
            is the number of exchange gates :math:`U_{1,\mathrm{ex}}` per layer.
        wires (Iterable or Wires): Wires that the template acts on. Accepts an iterable of numbers
            or strings, or a Wires object.
        init_state (array[int]): length ``len(wires)`` vector representing the Hartree-Fock state
            used to initialize the wires

    Raises:
        ValueError: if inputs do not have the correct format

    .. UsageDetails::

        #. The number of wires :math:`N` has to be equal to the number of
           spin orbitals included in the active space.

        #. The number of trainable parameters scales linearly with the number of layers as
           :math:`2D(N-1)`.

        An example of how to use this template is shown below:

        .. code-block:: python

            import pennylane as qml
            from pennylane.templates import ParticleConservingU1
            from functools import partial

            # Build the electronic Hamiltonian from a local .xyz file
            h, qubits = qml.qchem.molecular_hamiltonian("h2", "h2.xyz")

            # Define the Hartree-Fock state
            electrons = 2
            ref_state = qml.qchem.hf_state(electrons, qubits)

            # Define the device
            dev = qml.device('default.qubit', wires=qubits)

            # Define the ansatz
            ansatz = partial(ParticleConservingU1, init_state=ref_state)

            # Define the cost function
            cost_fn = qml.ExpvalCost(ansatz, h, dev)

            # Compute the expectation value of 'h'
            layers = 2
            params = qml.init.particle_conserving_u1_normal(layers, qubits)
            print(cost_fn(params))
    """

    wires = Wires(wires)

    layers = weights.shape[0]

    if len(wires) < 2:
        raise ValueError(
            "This template requires the number of qubits to be greater than one; a wire sequence with {} elements"
            .format(len(wires)))

    expected_shape = (layers, len(wires) - 1, 2)
    check_shape(
        weights,
        expected_shape,
        msg="'weights' must be of shape {}; got {}".format(
            expected_shape, get_shape(weights)),
    )

    nm_wires = [wires.subset([l, l + 1]) for l in range(0, len(wires) - 1, 2)]
    nm_wires += [wires.subset([l, l + 1]) for l in range(1, len(wires) - 1, 2)]

    qml.BasisState(init_state, wires=wires)

    for l in range(layers):
        for i, wires_ in enumerate(nm_wires):
            u1_ex_gate(weights[l, i, 0], weights[l, i, 1], wires=wires_)
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.24"),
        ],
    )
    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

    @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.PauliRot(3.14, "XX", wires=[0, 1]), 1, "RX(3.14)"),
            (qml.PauliRot(3.14, "YZ", wires=[0, 1]), 1, "RZ(3.14)"),
            (qml.PauliRot(3.14, "IXYZI", wires=[0, 1, 2, 3, 4
                                                ]), 0, "RI(3.14)"),
            (qml.PauliRot(3.14, "IXYZI", wires=[0, 1, 2, 3, 4
                                                ]), 1, "RX(3.14)"),
            (qml.PauliRot(3.14, "IXYZI", wires=[0, 1, 2, 3, 4
                                                ]), 2, "RY(3.14)"),
            (qml.PauliRot(3.14, "IXYZI", wires=[0, 1, 2, 3, 4
                                                ]), 3, "RZ(3.14)"),
            (qml.PauliRot(3.14, "IXYZI", wires=[0, 1, 2, 3, 4
                                                ]), 4, "RI(3.14)"),
            (qml.MultiRZ(3.14, wires=[0, 1]), 0, "RZ(3.14)"),
            (qml.MultiRZ(3.14, wires=[0, 1]), 1, "RZ(3.14)"),
            (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([[2, 0], [0, 2]]),
                                  np.array([1, 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.InterferometerUnitary(
                np.eye(4), wires=[1, 3]), 1, "InterferometerUnitary(M0)"),
            (qml.InterferometerUnitary(
                np.eye(4), wires=[1, 3]), 3, "InterferometerUnitary(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"),
            (qml.PauliX(wires=[1]).inv(), 1, "X⁻¹"),
            (qml.CNOT(wires=[0, 1]).inv(), 1, "X⁻¹"),
            (qml.CNOT(wires=[0, 1]).inv(), 0, "C"),
            (qml.Toffoli(wires=[0, 2, 1]).inv(), 1, "X⁻¹"),
            (qml.Toffoli(wires=[0, 2, 1]).inv(), 0, "C"),
            (qml.Toffoli(wires=[0, 2, 1]).inv(), 2, "C"),
            (qml.measure.sample(wires=[0, 1]), 0,
             "basis"),  # not providing an observable in
            (qml.measure.sample(wires=[0, 1]), 1,
             "basis"),  # sample gets displayed as raw
            (two_wire_quantum_tape(), 0, "QuantumTape:T0"),
            (two_wire_quantum_tape(), 1, "QuantumTape:T0"),
        ],
    )
    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([[2, 0], [0, 2]]),
                                  np.array([1, 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.InterferometerUnitary(
                np.eye(4), wires=[1, 3]), 1, "InterferometerUnitary(M0)"),
            (qml.InterferometerUnitary(
                np.eye(4), wires=[1, 3]), 3, "InterferometerUnitary(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"),
            (qml.QuadOperator(3.14, wires=[1]), 1, "cos(3.14)x+sin(3.14)p"),
            (qml.PauliX(wires=[1]).inv(), 1, "X^-1"),
            (qml.CNOT(wires=[0, 1]).inv(), 1, "X^-1"),
            (qml.CNOT(wires=[0, 1]).inv(), 0, "C"),
            (qml.Toffoli(wires=[0, 2, 1]).inv(), 1, "X^-1"),
            (qml.Toffoli(wires=[0, 2, 1]).inv(), 0, "C"),
            (qml.Toffoli(wires=[0, 2, 1]).inv(), 2, "C"),
            (qml.measure.sample(wires=[0, 1]), 0,
             "basis"),  # not providing an observable in
            (qml.measure.sample(wires=[0, 1]), 1,
             "basis"),  # sample gets displayed as raw
            (two_wire_quantum_tape(), 0, "QuantumTape:T0"),
            (two_wire_quantum_tape(), 1, "QuantumTape:T0"),
        ],
    )
    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]",
            ),
            (qml.probs([0]), 0, "Probs"),
            (state(), 0, "State"),
        ],
    )
    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]",
            ),
            (qml.probs([0]), 0, "Probs"),
            (state(), 0, "State"),
        ],
    )
    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)
 def circuit():
     qml.BasisState(np.array([1, 0, 1]), wires=[0, 1, 2])
     op(wires=[0, 1, 2])
     return qml.expval(qml.PauliZ(0)), qml.expval(
         qml.PauliZ(1)), qml.expval(qml.PauliZ(2))
Example #29
0
 def circuit(weight):
     qml.BasisState(init_state, wires=wires)
     qml.templates.layers.particle_conserving_u2.u2_ex_gate(
         weight, wires)
     return qml.expval(qml.PauliZ(0))
 def circuit():
     qml.BasisState(np.array([1]), wires=[0])
     op(wires=0).inv().inv().inv()
     return qml.expval(qml.PauliZ(0))