Exemplo n.º 1
0
def entangler(par1, par2, wires):
    """Implements a two qubit unitary consisting of a controlled-Z entangler and Pauli-Y rotations.

    Args:
         par1 (float or qml.Variable): parameter of first Pauli-Y rotation
         par2 (float or qml.Variable): parameter of second Pauli-Y rotation
         wires (Wires): two wire indices that unitary acts on
    """

    CZ(wires=wires)
    RY(par1, wires=wires[0])
    RY(par2, wires=wires[1])
Exemplo n.º 2
0
def AngleEmbedding(features, wires, rotation="X"):
    r"""
    Encodes :math:`N` features into the rotation angles of :math:`n` qubits, where :math:`N \leq n`.

    The rotations can be chosen as either :class:`~pennylane.ops.RX`, :class:`~pennylane.ops.RY`
    or :class:`~pennylane.ops.RZ` gates, as defined by the ``rotation`` parameter:

    * ``rotation='X'`` uses the features as angles of RX rotations

    * ``rotation='Y'`` uses the features as angles of RY rotations

    * ``rotation='Z'`` uses the features as angles of RZ rotations

    The length of ``features`` has to be smaller or equal to the number of qubits. If there are fewer entries in
    ``features`` than rotations, the circuit does not apply the remaining rotation gates.

    Args:
        features (array): input array of shape ``(N,)``, where N is the number of input features to embed,
            with :math:`N\leq n`
        wires (Sequence[int] or int): qubit indices that the template acts on
        rotation (str): Type of rotations used

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

    #############
    # Input checks

    _check_no_variable(rotation, msg="'rotation' cannot be differentiable")

    wires = _check_wires(wires)

    _check_shape(
        features,
        (len(wires), ),
        bound="max",
        msg="'features' must be of shape {} or smaller; "
        "got {}.".format((len(wires), ), _get_shape(features)),
    )
    _check_type(rotation, [str],
                msg="'rotation' must be a string; got {}".format(rotation))

    _check_is_in_options(
        rotation,
        ["X", "Y", "Z"],
        msg="did not recognize option {} for 'rotation'.".format(rotation),
    )

    ###############

    if rotation == "X":
        for f, w in zip(features, wires):
            RX(f, wires=w)
    elif rotation == "Y":
        for f, w in zip(features, wires):
            RY(f, wires=w)
    elif rotation == "Z":
        for f, w in zip(features, wires):
            RZ(f, wires=w)
Exemplo n.º 3
0
def AngleEmbedding(features, wires, rotation='X'):
    r"""
    Encodes :math:`N` features into the rotation angles of :math:`n` qubits, where :math:`N \leq n`.

    The rotations can be chosen as either :class:`~pennylane.ops.RX`, :class:`~pennylane.ops.RY`
    or :class:`~pennylane.ops.RZ` gates, as defined by the ``rotation`` parameter:

    * ``rotation='X'`` uses the features as angles of RX rotations

    * ``rotation='Y'`` uses the features as angles of RY rotations

    * ``rotation='Z'`` uses the features as angles of RZ rotations

    The length of ``features`` has to be smaller or equal to the number of qubits. If there are fewer entries in
    ``features`` than rotations, the circuit does not apply the remaining rotation gates.

    This embedding method can also be used to encode a binary sequence into a basis state. For example, to prepare
    basis state :math:`|0,1,1,0\rangle`, choose ``rotation='X'`` and use the
    feature vector :math:`[0, \pi/2, \pi/2, 0]`. Alternatively, one can use the :mod:`BasisEmbedding()` template.

    Args:
        features (array): Input array of shape ``(N,)``, where N is the number of features
            to embed. ``N`` must be smaller or equal to the total number of wires.
        wires (Sequence[int]): sequence of qubit indices that the template acts on

    Keyword Args:
        rotation (str): Type of rotations used

    Raises:
        ValueError: if ``features`` or ``wires`` is invalid
    """

    if not isinstance(wires, Iterable):
        raise ValueError(
            "Wires must be passed as a list of integers; got {}.".format(
                wires))

    if len(features) > len(wires):
        raise ValueError(
            "Number of features to embed cannot be larger than number of wires, which is {}; "
            "got {}.".format(len(wires), len(features)))
    if rotation == 'X':
        for f, w in zip(features, wires):
            RX(f, wires=w)

    elif rotation == 'Y':
        for f, w in zip(features, wires):
            RY(f, wires=w)

    elif rotation == 'Z':
        for f, w in zip(features, wires):
            RZ(f, wires=w)

    else:
        raise ValueError(
            "Rotation has to be `X`, `Y` or `Z`; got {}.".format(rotation))
Exemplo n.º 4
0
def AngleEmbedding(features, wires, rotation='X'):
    r"""
    Encodes :math:`N` features into the rotation angles of :math:`n` qubits, where :math:`N \leq n`.

    The rotations can be chosen as either :class:`~pennylane.ops.RX`, :class:`~pennylane.ops.RY`
    or :class:`~pennylane.ops.RZ` gates, as defined by the ``rotation`` parameter:

    * ``rotation='X'`` uses the features as angles of RX rotations

    * ``rotation='Y'`` uses the features as angles of RY rotations

    * ``rotation='Z'`` uses the features as angles of RZ rotations

    The length of ``features`` has to be smaller or equal to the number of qubits. If there are fewer entries in
    ``features`` than rotations, the circuit does not apply the remaining rotation gates.

    Args:
        features (array): input array of shape ``(N,)``, where N is the number of input features to embed,
            with :math:`N\leq n`
        wires (Sequence[int] or int): qubit indices that the template acts on
        rotation (str): Type of rotations used

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

    #############
    # Input checks
    _check_no_variable([rotation], ['rotation'])
    wires, n_wires = _check_wires(wires)

    msg = "AngleEmbedding cannot process more features than number of qubits {};" \
          "got {}.".format(n_wires, len(features))
    _check_shape(features, (n_wires,), bound='max', msg=msg)
    _check_type(rotation, [str])

    msg = "Rotation strategy {} not recognized.".format(rotation)
    _check_hyperp_is_in_options(rotation, ['X', 'Y', 'Z'], msg=msg)
    ###############

    if rotation == 'X':
        for f, w in zip(features, wires):
            RX(f, wires=w)
    elif rotation == 'Y':
        for f, w in zip(features, wires):
            RY(f, wires=w)
    elif rotation == 'Z':
        for f, w in zip(features, wires):
            RZ(f, wires=w)
Exemplo n.º 5
0
def strongly_entangling_layer(weights, wires, r, imprimitive):
    r"""A layer applying rotations on each qubit followed by cascades of 2-qubit entangling gates.

    Args:
        weights (array[float]): array of weights of shape ``(len(wires), 3)``
        wires (Sequence[int]): sequence of qubit indices that the template acts on
        r (int): range of the imprimitive gates of this layer, defaults to 1
        imprimitive (pennylane.ops.Operation): two-qubit gate to use, defaults to :class:`~pennylane.ops.CNOT`
    """

    for i, wire in enumerate(wires):
        RZ(weights[i, 0], wires=wire)
        RY(weights[i, 1], wires=wire)
        RZ(weights[i, 2], wires=wire)

    n_wires = len(wires)
    if n_wires > 1:
        for i in range(n_wires):
            imprimitive(wires=[wires[i], wires[(i + r) % n_wires]])
Exemplo n.º 6
0
def ParametrizedTemplateDouble(par1, par2, wires):
    CRX(par1, wires=wires)
    RY(par2, wires=wires[0])
Exemplo n.º 7
0
def KwargTemplate(par, wires, a=True):
    if a:
        T(wires=wires)
    RY(par, wires=wires)
Exemplo n.º 8
0
def ParametrizedTemplate(par1, par2, wires):
    RX(par1, wires=wires)
    RY(par2, wires=wires)