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])
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)
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))
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)
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]])
def ParametrizedTemplateDouble(par1, par2, wires): CRX(par1, wires=wires) RY(par2, wires=wires[0])
def KwargTemplate(par, wires, a=True): if a: T(wires=wires) RY(par, wires=wires)
def ParametrizedTemplate(par1, par2, wires): RX(par1, wires=wires) RY(par2, wires=wires)