Source code for pennylane.ops.qubit.non_parametric_ops
# Copyright 2018-2021 Xanadu Quantum Technologies Inc.# Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at# http://www.apache.org/licenses/LICENSE-2.0# Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License."""This submodule contains the discrete-variable quantum operations that donot depend on any parameters."""# pylint:disable=abstract-method,arguments-differ,protected-access,invalid-overridden-method, no-memberimportcmathfromcopyimportcopyfromfunctoolsimportlru_cachefromtypingimportOptional,Unionimportnumpyasnpfromscipyimportsparseimportpennylaneasqmlfrompennylane.operationimportObservable,Operationfrompennylane.typingimportTensorLikefrompennylane.wiresimportWires,WiresLikeINV_SQRT2=1/qml.math.sqrt(2)
[docs]classHadamard(Observable,Operation):r"""Hadamard(wires) The Hadamard operator .. math:: H = \frac{1}{\sqrt{2}}\begin{bmatrix} 1 & 1\\ 1 & -1\end{bmatrix}. .. seealso:: The equivalent short-form alias :class:`~H` **Details:** * Number of wires: 1 * Number of parameters: 0 Args: wires (Sequence[int] or int): the wire the operation acts on """num_wires=1"""int: Number of wires that the operator acts on."""num_params=0"""int: Number of trainable parameters that the operator depends on."""_queue_category="_ops"def__init__(self,wires:WiresLike,id:Optional[str]=None):super().__init__(wires=wires,id=id)
[docs]@staticmethod@lru_cache()defcompute_matrix()->np.ndarray:# pylint: disable=arguments-differr"""Representation of the operator as a canonical matrix in the computational basis (static method). The canonical matrix is the textbook matrix representation that does not consider wires. Implicitly, this assumes that the wires of the operator correspond to the global wire order. .. seealso:: :meth:`~.Hadamard.matrix` Returns: ndarray: matrix **Example** >>> print(qml.Hadamard.compute_matrix()) [[ 0.70710678 0.70710678] [ 0.70710678 -0.70710678]] """returnnp.array([[INV_SQRT2,INV_SQRT2],[INV_SQRT2,-INV_SQRT2]])
[docs]@staticmethoddefcompute_eigvals()->np.ndarray:# pylint: disable=arguments-differr"""Eigenvalues of the operator in the computational basis (static method). If :attr:`diagonalizing_gates` are specified and implement a unitary :math:`U^{\dagger}`, the operator can be reconstructed as .. math:: O = U \Sigma U^{\dagger}, where :math:`\Sigma` is the diagonal matrix containing the eigenvalues. Otherwise, no particular order for the eigenvalues is guaranteed. .. seealso:: :meth:`~.Hadamard.eigvals` Returns: array: eigenvalues **Example** >>> print(qml.Hadamard.compute_eigvals()) [ 1 -1] """returnqml.pauli.pauli_eigs(1)
[docs]@staticmethoddefcompute_diagonalizing_gates(wires:WiresLike)->list[qml.operation.Operator]:r"""Sequence of gates that diagonalize the operator in the computational basis (static method). Given the eigendecomposition :math:`O = U \Sigma U^{\dagger}` where :math:`\Sigma` is a diagonal matrix containing the eigenvalues, the sequence of diagonalizing gates implements the unitary :math:`U^{\dagger}`. The diagonalizing gates rotate the state into the eigenbasis of the operator. .. seealso:: :meth:`~.Hadamard.diagonalizing_gates`. Args: wires (Iterable[Any], Wires): wires that the operator acts on Returns: list[.Operator]: list of diagonalizing gates **Example** >>> print(qml.Hadamard.compute_diagonalizing_gates(wires=[0])) [RY(-0.7853981633974483, wires=[0])] """return[qml.RY(-np.pi/4,wires=wires)]
[docs]@staticmethoddefcompute_decomposition(wires:WiresLike)->list[qml.operation.Operator]:r"""Representation of the operator as a product of other operators (static method). .. math:: O = O_1 O_2 \dots O_n. .. seealso:: :meth:`~.Hadamard.decomposition`. Args: wires (Any, Wires): Wire that the operator acts on. Returns: list[Operator]: decomposition of the operator **Example:** >>> print(qml.Hadamard.compute_decomposition(0)) [PhaseShift(1.5707963267948966, wires=[0]), RX(1.5707963267948966, wires=[0]), PhaseShift(1.5707963267948966, wires=[0])] """return[qml.PhaseShift(np.pi/2,wires=wires),qml.RX(np.pi/2,wires=wires),qml.PhaseShift(np.pi/2,wires=wires),]
H=Hadamardr"""H(wires)The Hadamard operator.. math:: H = \frac{1}{\sqrt{2}}\begin{bmatrix} 1 & 1\\ 1 & -1\end{bmatrix}... seealso:: The equivalent long-form alias :class:`~Hadamard`**Details:*** Number of wires: 1* Number of parameters: 0Args: wires (Sequence[int] or int): the wire the operation acts on"""
[docs]classPauliX(Observable,Operation):r""" The Pauli X operator .. math:: \sigma_x = \begin{bmatrix} 0 & 1 \\ 1 & 0\end{bmatrix}. .. seealso:: The equivalent short-form alias :class:`~X` **Details:** * Number of wires: 1 * Number of parameters: 0 Args: wires (Sequence[int] or int): the wire the operation acts on """num_wires=1"""int: Number of wires that the operator acts on."""num_params=0"""int: Number of trainable parameters that the operator depends on."""basis="X"batch_size=None_queue_category="_ops"@propertydefpauli_rep(self):ifself._pauli_repisNone:self._pauli_rep=qml.pauli.PauliSentence({qml.pauli.PauliWord({self.wires[0]:"X"}):1.0})returnself._pauli_repdef__init__(self,wires:WiresLike,id:Optional[str]=None):super().__init__(wires=wires,id=id)
[docs]@staticmethod@lru_cache()defcompute_matrix()->np.ndarray:# pylint: disable=arguments-differr"""Representation of the operator as a canonical matrix in the computational basis (static method). The canonical matrix is the textbook matrix representation that does not consider wires. Implicitly, this assumes that the wires of the operator correspond to the global wire order. .. seealso:: :meth:`~.X.matrix` Returns: ndarray: matrix **Example** >>> print(qml.X.compute_matrix()) [[0 1] [1 0]] """returnnp.array([[0,1],[1,0]])
[docs]@staticmethoddefcompute_eigvals()->np.ndarray:# pylint: disable=arguments-differr"""Eigenvalues of the operator in the computational basis (static method). If :attr:`diagonalizing_gates` are specified and implement a unitary :math:`U^{\dagger}`, the operator can be reconstructed as .. math:: O = U \Sigma U^{\dagger}, where :math:`\Sigma` is the diagonal matrix containing the eigenvalues. Otherwise, no particular order for the eigenvalues is guaranteed. .. seealso:: :meth:`~.X.eigvals` Returns: array: eigenvalues **Example** >>> print(qml.X.compute_eigvals()) [ 1 -1] """returnqml.pauli.pauli_eigs(1)
[docs]@staticmethoddefcompute_diagonalizing_gates(wires:WiresLike)->list[qml.operation.Operator]:r"""Sequence of gates that diagonalize the operator in the computational basis (static method). Given the eigendecomposition :math:`O = U \Sigma U^{\dagger}` where :math:`\Sigma` is a diagonal matrix containing the eigenvalues, the sequence of diagonalizing gates implements the unitary :math:`U^{\dagger}`. The diagonalizing gates rotate the state into the eigenbasis of the operator. .. seealso:: :meth:`~.X.diagonalizing_gates`. Args: wires (Iterable[Any], Wires): wires that the operator acts on Returns: list[.Operator]: list of diagonalizing gates **Example** >>> print(qml.X.compute_diagonalizing_gates(wires=[0])) [H(0)] """return[Hadamard(wires=wires)]
[docs]@staticmethoddefcompute_decomposition(wires:WiresLike)->list[qml.operation.Operator]:r"""Representation of the operator as a product of other operators (static method). .. math:: O = O_1 O_2 \dots O_n. .. seealso:: :meth:`~.X.decomposition`. Args: wires (Any, Wires): Wire that the operator acts on. Returns: list[Operator]: decomposition into lower level operations **Example:** >>> print(qml.X.compute_decomposition(0)) [PhaseShift(1.5707963267948966, wires=[0]), RX(3.141592653589793, wires=[0]), PhaseShift(1.5707963267948966, wires=[0])] """return[qml.PhaseShift(np.pi/2,wires=wires),qml.RX(np.pi,wires=wires),qml.PhaseShift(np.pi/2,wires=wires),]
[docs]defsingle_qubit_rot_angles(self)->list[TensorLike]:# X = RZ(-\pi/2) RY(\pi) RZ(\pi/2)return[np.pi/2,np.pi,-np.pi/2]
X=PauliXr"""The Pauli X operator.. math:: \sigma_x = \begin{bmatrix} 0 & 1 \\ 1 & 0\end{bmatrix}... seealso:: The equivalent long-form alias :class:`~PauliX`**Details:*** Number of wires: 1* Number of parameters: 0Args: wires (Sequence[int] or int): the wire the operation acts on"""
[docs]classPauliY(Observable,Operation):r""" The Pauli Y operator .. math:: \sigma_y = \begin{bmatrix} 0 & -i \\ i & 0\end{bmatrix}. .. seealso:: The equivalent short-form alias :class:`~Y` **Details:** * Number of wires: 1 * Number of parameters: 0 Args: wires (Sequence[int] or int): the wire the operation acts on """num_wires=1"""int: Number of wires that the operator acts on."""num_params=0"""int: Number of trainable parameters that the operator depends on."""basis="Y"batch_size=None_queue_category="_ops"@propertydefpauli_rep(self):ifself._pauli_repisNone:self._pauli_rep=qml.pauli.PauliSentence({qml.pauli.PauliWord({self.wires[0]:"Y"}):1.0})returnself._pauli_repdef__init__(self,wires:WiresLike,id:Optional[str]=None):super().__init__(wires=wires,id=id)def__repr__(self)->str:"""String representation."""wire=self.wires[0]ifisinstance(wire,str):returnf"Y('{wire}')"returnf"Y({wire})"
[docs]@staticmethod@lru_cache()defcompute_matrix()->np.ndarray:# pylint: disable=arguments-differr"""Representation of the operator as a canonical matrix in the computational basis (static method). The canonical matrix is the textbook matrix representation that does not consider wires. Implicitly, this assumes that the wires of the operator correspond to the global wire order. .. seealso:: :meth:`~.Y.matrix` Returns: ndarray: matrix **Example** >>> print(qml.Y.compute_matrix()) [[ 0.+0.j -0.-1.j] [ 0.+1.j 0.+0.j]] """returnnp.array([[0,-1j],[1j,0]])
[docs]@staticmethoddefcompute_eigvals()->np.ndarray:# pylint: disable=arguments-differr"""Eigenvalues of the operator in the computational basis (static method). If :attr:`diagonalizing_gates` are specified and implement a unitary :math:`U^{\dagger}`, the operator can be reconstructed as .. math:: O = U \Sigma U^{\dagger}, where :math:`\Sigma` is the diagonal matrix containing the eigenvalues. Otherwise, no particular order for the eigenvalues is guaranteed. .. seealso:: :meth:`~.Y.eigvals` Returns: array: eigenvalues **Example** >>> print(qml.Y.compute_eigvals()) [ 1 -1] """returnqml.pauli.pauli_eigs(1)
[docs]@staticmethoddefcompute_diagonalizing_gates(wires:WiresLike)->list[qml.operation.Operator]:r"""Sequence of gates that diagonalize the operator in the computational basis (static method). Given the eigendecomposition :math:`O = U \Sigma U^{\dagger}` where :math:`\Sigma` is a diagonal matrix containing the eigenvalues, the sequence of diagonalizing gates implements the unitary :math:`U^{\dagger}`. The diagonalizing gates rotate the state into the eigenbasis of the operator. .. seealso:: :meth:`~.Y.diagonalizing_gates`. Args: wires (Iterable[Any], Wires): wires that the operator acts on Returns: list[.Operator]: list of diagonalizing gates **Example** >>> print(qml.Y.compute_diagonalizing_gates(wires=[0])) [Z(0), S(0), H(0)] """return[Z(wires=wires),S(wires=wires),Hadamard(wires=wires),]
[docs]@staticmethoddefcompute_decomposition(wires:WiresLike)->list[qml.operation.Operator]:r"""Representation of the operator as a product of other operators (static method). .. math:: O = O_1 O_2 \dots O_n. .. seealso:: :meth:`~.Y.decomposition`. Args: wires (Any, Wires): Single wire that the operator acts on. Returns: list[Operator]: decomposition into lower level operations **Example:** >>> print(qml.Y.compute_decomposition(0)) [PhaseShift(1.5707963267948966, wires=[0]), RY(3.141592653589793, wires=[0]), PhaseShift(1.5707963267948966, wires=[0])] """return[qml.PhaseShift(np.pi/2,wires=wires),qml.RY(np.pi,wires=wires),qml.PhaseShift(np.pi/2,wires=wires),]
[docs]defsingle_qubit_rot_angles(self)->list[TensorLike]:# Y = RZ(0) RY(\pi) RZ(0)return[0.0,np.pi,0.0]
Y=PauliYr"""The Pauli Y operator.. math:: \sigma_y = \begin{bmatrix} 0 & -i \\ i & 0\end{bmatrix}... seealso:: The equivalent long-form alias :class:`~PauliY`**Details:*** Number of wires: 1* Number of parameters: 0Args: wires (Sequence[int] or int): the wire the operation acts on"""
[docs]classPauliZ(Observable,Operation):r""" The Pauli Z operator .. math:: \sigma_z = \begin{bmatrix} 1 & 0 \\ 0 & -1\end{bmatrix}. .. seealso:: The equivalent short-form alias :class:`~Z` **Details:** * Number of wires: 1 * Number of parameters: 0 Args: wires (Sequence[int] or int): the wire the operation acts on """num_wires=1num_params=0"""int: Number of trainable parameters that the operator depends on."""basis="Z"batch_size=None_queue_category="_ops"@propertydefpauli_rep(self):ifself._pauli_repisNone:self._pauli_rep=qml.pauli.PauliSentence({qml.pauli.PauliWord({self.wires[0]:"Z"}):1.0})returnself._pauli_repdef__init__(self,wires:WiresLike,id:Optional[str]=None):super().__init__(wires=wires,id=id)def__repr__(self)->str:"""String representation."""wire=self.wires[0]ifisinstance(wire,str):returnf"Z('{wire}')"returnf"Z({wire})"
[docs]@staticmethod@lru_cache()defcompute_matrix()->np.ndarray:# pylint: disable=arguments-differr"""Representation of the operator as a canonical matrix in the computational basis (static method). The canonical matrix is the textbook matrix representation that does not consider wires. Implicitly, this assumes that the wires of the operator correspond to the global wire order. .. seealso:: :meth:`~.Z.matrix` Returns: ndarray: matrix **Example** >>> print(qml.Z.compute_matrix()) [[ 1 0] [ 0 -1]] """returnnp.array([[1,0],[0,-1]])
[docs]@staticmethoddefcompute_eigvals()->np.ndarray:# pylint: disable=arguments-differr"""Eigenvalues of the operator in the computational basis (static method). If :attr:`diagonalizing_gates` are specified and implement a unitary :math:`U^{\dagger}`, the operator can be reconstructed as .. math:: O = U \Sigma U^{\dagger}, where :math:`\Sigma` is the diagonal matrix containing the eigenvalues. Otherwise, no particular order for the eigenvalues is guaranteed. .. seealso:: :meth:`~.Z.eigvals` Returns: array: eigenvalues **Example** >>> print(qml.Z.compute_eigvals()) [ 1 -1] """returnqml.pauli.pauli_eigs(1)
[docs]@staticmethoddefcompute_diagonalizing_gates(# pylint: disable=unused-argumentwires:WiresLike,)->list[qml.operation.Operator]:r"""Sequence of gates that diagonalize the operator in the computational basis (static method). Given the eigendecomposition :math:`O = U \Sigma U^{\dagger}` where :math:`\Sigma` is a diagonal matrix containing the eigenvalues, the sequence of diagonalizing gates implements the unitary :math:`U^{\dagger}`. The diagonalizing gates rotate the state into the eigenbasis of the operator. .. seealso:: :meth:`~.Z.diagonalizing_gates`. Args: wires (Iterable[Any] or Wires): wires that the operator acts on Returns: list[.Operator]: list of diagonalizing gates **Example** >>> print(qml.Z.compute_diagonalizing_gates(wires=[0])) [] """return[]
[docs]@staticmethoddefcompute_decomposition(wires:WiresLike)->list[qml.operation.Operator]:r"""Representation of the operator as a product of other operators (static method). .. math:: O = O_1 O_2 \dots O_n. .. seealso:: :meth:`~.Z.decomposition`. Args: wires (Any, Wires): Single wire that the operator acts on. Returns: list[Operator]: decomposition into lower level operations **Example:** >>> print(qml.Z.compute_decomposition(0)) [PhaseShift(3.141592653589793, wires=[0])] """return[qml.PhaseShift(np.pi,wires=wires)]
[docs]defsingle_qubit_rot_angles(self)->list[TensorLike]:# Z = RZ(\pi) RY(0) RZ(0)return[np.pi,0.0,0.0]
Z=PauliZr"""The Pauli Z operator.. math:: \sigma_z = \begin{bmatrix} 1 & 0 \\ 0 & -1\end{bmatrix}... seealso:: The equivalent long-form alias :class:`~PauliZ`**Details:*** Number of wires: 1* Number of parameters: 0Args: wires (Sequence[int] or int): the wire the operation acts on"""
[docs]classS(Operation):r"""S(wires) The single-qubit phase gate .. math:: S = \begin{bmatrix} 1 & 0 \\ 0 & i \end{bmatrix}. **Details:** * Number of wires: 1 * Number of parameters: 0 Args: wires (Sequence[int] or int): the wire the operation acts on """num_wires=1num_params=0"""int: Number of trainable parameters that the operator depends on."""basis="Z"batch_size=None@propertydefpauli_rep(self):ifself._pauli_repisNone:self._pauli_rep=qml.pauli.PauliSentence({qml.pauli.PauliWord({self.wires[0]:"I"}):0.5+0.5j,qml.pauli.PauliWord({self.wires[0]:"Z"}):0.5-0.5j,})returnself._pauli_repdef__repr__(self)->str:"""String representation."""wire=self.wires[0]ifisinstance(wire,str):returnf"S('{wire}')"returnf"S({wire})"
[docs]@staticmethod@lru_cache()defcompute_matrix()->np.ndarray:# pylint: disable=arguments-differr"""Representation of the operator as a canonical matrix in the computational basis (static method). The canonical matrix is the textbook matrix representation that does not consider wires. Implicitly, this assumes that the wires of the operator correspond to the global wire order. .. seealso:: :meth:`~.S.matrix` Returns: ndarray: matrix **Example** >>> print(qml.S.compute_matrix()) [[1.+0.j 0.+0.j] [0.+0.j 0.+1.j]] """returnnp.array([[1,0],[0,1j]])
[docs]@staticmethoddefcompute_eigvals()->np.ndarray:# pylint: disable=arguments-differr"""Eigenvalues of the operator in the computational basis (static method). If :attr:`diagonalizing_gates` are specified and implement a unitary :math:`U^{\dagger}`, the operator can be reconstructed as .. math:: O = U \Sigma U^{\dagger}, where :math:`\Sigma` is the diagonal matrix containing the eigenvalues. Otherwise, no particular order for the eigenvalues is guaranteed. .. seealso:: :meth:`~.S.eigvals` Returns: array: eigenvalues **Example** >>> print(qml.S.compute_eigvals()) [1.+0.j 0.+1.j] """returnnp.array([1,1j])
[docs]@staticmethoddefcompute_decomposition(wires:WiresLike)->list[qml.operation.Operator]:r"""Representation of the operator as a product of other operators (static method). .. math:: O = O_1 O_2 \dots O_n. .. seealso:: :meth:`~.S.decomposition`. Args: wires (Any, Wires): Single wire that the operator acts on. Returns: list[Operator]: decomposition into lower level operations **Example:** >>> print(qml.S.compute_decomposition(0)) [PhaseShift(1.5707963267948966, wires=[0])] """return[qml.PhaseShift(np.pi/2,wires=wires)]
[docs]defsingle_qubit_rot_angles(self)->list[TensorLike]:# S = RZ(\pi/2) RY(0) RZ(0)return[np.pi/2,0.0,0.0]
[docs]classT(Operation):r"""T(wires) The single-qubit T gate .. math:: T = \begin{bmatrix} 1 & 0 \\ 0 & e^{\frac{i\pi}{4}} \end{bmatrix}. **Details:** * Number of wires: 1 * Number of parameters: 0 Args: wires (Sequence[int] or int): the wire the operation acts on """num_wires=1num_params=0"""int: Number of trainable parameters that the operator depends on."""basis="Z"batch_size=None@propertydefpauli_rep(self):ifself._pauli_repisNone:self._pauli_rep=qml.pauli.PauliSentence({qml.pauli.PauliWord({self.wires[0]:"I"}):(0.5+INV_SQRT2*(0.5+0.5j)),qml.pauli.PauliWord({self.wires[0]:"Z"}):(0.5-INV_SQRT2*(0.5+0.5j)),})returnself._pauli_repdef__repr__(self)->str:"""String representation."""wire=self.wires[0]ifisinstance(wire,str):returnf"T('{wire}')"returnf"T({wire})"
[docs]@staticmethod@lru_cache()defcompute_matrix()->np.ndarray:# pylint: disable=arguments-differr"""Representation of the operator as a canonical matrix in the computational basis (static method). The canonical matrix is the textbook matrix representation that does not consider wires. Implicitly, this assumes that the wires of the operator correspond to the global wire order. .. seealso:: :meth:`~.T.matrix` Returns: ndarray: matrix **Example** >>> print(qml.T.compute_matrix()) [[1.+0.j 0. +0.j ] [0.+0.j 0.70710678+0.70710678j]] """returnnp.array([[1,0],[0,cmath.exp(1j*np.pi/4)]])
[docs]@staticmethoddefcompute_eigvals()->np.ndarray:# pylint: disable=arguments-differr"""Eigenvalues of the operator in the computational basis (static method). If :attr:`diagonalizing_gates` are specified and implement a unitary :math:`U^{\dagger}`, the operator can be reconstructed as .. math:: O = U \Sigma U^{\dagger}, where :math:`\Sigma` is the diagonal matrix containing the eigenvalues. Otherwise, no particular order for the eigenvalues is guaranteed. .. seealso:: :meth:`~.T.eigvals` Returns: array: eigenvalues **Example** >>> print(qml.T.compute_eigvals()) [1.+0.j 0.70710678+0.70710678j] """returnnp.array([1,cmath.exp(1j*np.pi/4)])
[docs]@staticmethoddefcompute_decomposition(wires:WiresLike)->list[qml.operation.Operator]:r"""Representation of the operator as a product of other operators (static method). .. math:: O = O_1 O_2 \dots O_n. .. seealso:: :meth:`~.T.decomposition`. Args: wires (Any, Wires): Single wire that the operator acts on. Returns: list[Operator]: decomposition into lower level operations **Example:** >>> print(qml.T.compute_decomposition(0)) [PhaseShift(0.7853981633974483, wires=[0])] """return[qml.PhaseShift(np.pi/4,wires=wires)]
[docs]defsingle_qubit_rot_angles(self)->list[TensorLike]:# T = RZ(\pi/4) RY(0) RZ(0)return[np.pi/4,0.0,0.0]
[docs]classSX(Operation):r"""SX(wires) The single-qubit Square-Root X operator. .. math:: SX = \sqrt{X} = \frac{1}{2} \begin{bmatrix} 1+i & 1-i \\ 1-i & 1+i \\ \end{bmatrix}. **Details:** * Number of wires: 1 * Number of parameters: 0 Args: wires (Sequence[int] or int): the wire the operation acts on """num_wires=1num_params=0"""int: Number of trainable parameters that the operator depends on."""basis="X"@propertydefpauli_rep(self):ifself._pauli_repisNone:self._pauli_rep=qml.pauli.PauliSentence({qml.pauli.PauliWord({self.wires[0]:"I"}):(0.5+0.5j),qml.pauli.PauliWord({self.wires[0]:"X"}):(0.5-0.5j),})returnself._pauli_repdef__repr__(self)->str:"""String representation."""wire=self.wires[0]ifisinstance(wire,str):returnf"SX('{wire}')"returnf"SX({wire})"
[docs]@staticmethod@lru_cache()defcompute_matrix()->np.ndarray:# pylint: disable=arguments-differr"""Representation of the operator as a canonical matrix in the computational basis (static method). The canonical matrix is the textbook matrix representation that does not consider wires. Implicitly, this assumes that the wires of the operator correspond to the global wire order. .. seealso:: :meth:`~.SX.matrix` Returns: ndarray: matrix **Example** >>> print(qml.SX.compute_matrix()) [[0.5+0.5j 0.5-0.5j] [0.5-0.5j 0.5+0.5j]] """return0.5*np.array([[1+1j,1-1j],[1-1j,1+1j]])
[docs]@staticmethoddefcompute_eigvals()->np.ndarray:# pylint: disable=arguments-differr"""Eigenvalues of the operator in the computational basis (static method). If :attr:`diagonalizing_gates` are specified and implement a unitary :math:`U^{\dagger}`, the operator can be reconstructed as .. math:: O = U \Sigma U^{\dagger}, where :math:`\Sigma` is the diagonal matrix containing the eigenvalues. Otherwise, no particular order for the eigenvalues is guaranteed. .. seealso:: :meth:`~.SX.eigvals` Returns: array: eigenvalues **Example** >>> print(qml.SX.compute_eigvals()) [1.+0.j 0.+1.j] """returnnp.array([1,1j])
[docs]@staticmethoddefcompute_decomposition(wires:WiresLike)->list[qml.operation.Operator]:r"""Representation of the operator as a product of other operators (static method). .. math:: O = O_1 O_2 \dots O_n. .. seealso:: :meth:`~.SX.decomposition`. Args: wires (Any, Wires): Single wire that the operator acts on. Returns: list[Operator]: decomposition into lower level operations **Example:** >>> print(qml.SX.compute_decomposition(0)) [RZ(1.5707963267948966, wires=[0]), RY(1.5707963267948966, wires=[0]), RZ(-3.141592653589793, wires=[0]), PhaseShift(1.5707963267948966, wires=[0])] """return[qml.RZ(np.pi/2,wires=wires),qml.RY(np.pi/2,wires=wires),qml.RZ(-np.pi,wires=wires),qml.PhaseShift(np.pi/2,wires=wires),]
[docs]classSWAP(Operation):r"""SWAP(wires) The swap operator .. math:: SWAP = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0\\ 0 & 1 & 0 & 0\\ 0 & 0 & 0 & 1 \end{bmatrix}. **Details:** * Number of wires: 2 * Number of parameters: 0 Args: wires (Sequence[int]): the wires the operation acts on """num_wires=2num_params=0"""int: Number of trainable parameters that the operator depends on."""batch_size=None@propertydefpauli_rep(self):ifself._pauli_repisNone:self._pauli_rep=qml.pauli.PauliSentence({qml.pauli.PauliWord({}):0.5,qml.pauli.PauliWord({self.wires[0]:"X",self.wires[1]:"X"}):0.5,qml.pauli.PauliWord({self.wires[0]:"Y",self.wires[1]:"Y"}):0.5,qml.pauli.PauliWord({self.wires[0]:"Z",self.wires[1]:"Z"}):0.5,})returnself._pauli_rep
[docs]@staticmethod@lru_cache()defcompute_matrix()->np.ndarray:# pylint: disable=arguments-differr"""Representation of the operator as a canonical matrix in the computational basis (static method). The canonical matrix is the textbook matrix representation that does not consider wires. Implicitly, this assumes that the wires of the operator correspond to the global wire order. .. seealso:: :meth:`~.SWAP.matrix` Returns: ndarray: matrix **Example** >>> print(qml.SWAP.compute_matrix()) [[1 0 0 0] [0 0 1 0] [0 1 0 0] [0 0 0 1]] """returnnp.array([[1,0,0,0],[0,0,1,0],[0,1,0,0],[0,0,0,1]])
[docs]@staticmethoddefcompute_decomposition(wires:WiresLike)->list[qml.operation.Operator]:r"""Representation of the operator as a product of other operators (static method). .. math:: O = O_1 O_2 \dots O_n. .. seealso:: :meth:`~.SWAP.decomposition`. Args: wires (Iterable, Wires): wires that the operator acts on Returns: list[Operator]: decomposition into lower level operations **Example:** >>> print(qml.SWAP.compute_decomposition((0,1))) [CNOT(wires=[0, 1]), CNOT(wires=[1, 0]), CNOT(wires=[0, 1])] """return[qml.CNOT(wires=[wires[0],wires[1]]),qml.CNOT(wires=[wires[1],wires[0]]),qml.CNOT(wires=[wires[0],wires[1]]),]
[docs]classECR(Operation):r""" ECR(wires) An echoed RZX(:math:`\pi/2`) gate. .. math:: ECR = {\frac{1}{\sqrt{2}}} \begin{bmatrix} 0 & 0 & 1 & i \\ 0 & 0 & i & 1 \\ 1 & -i & 0 & 0 \\ -i & 1 & 0 & 0 \end{bmatrix}. **Details:** * Number of wires: 2 * Number of parameters: 0 Args: wires (int): the subsystem the gate acts on id (str or None): String representing the operation (optional) """num_wires=2num_params=0batch_size=None@propertydefpauli_rep(self):ifself._pauli_repisNone:self._pauli_rep=qml.pauli.PauliSentence({qml.pauli.PauliWord({self.wires[0]:"X"}):INV_SQRT2,qml.pauli.PauliWord({self.wires[0]:"Y",self.wires[1]:"X"}):-INV_SQRT2,})returnself._pauli_rep
[docs]@staticmethoddefcompute_matrix()->np.ndarray:# pylint: disable=arguments-differr"""Representation of the operator as a canonical matrix in the computational basis (static method). The canonical matrix is the textbook matrix representation that does not consider wires. Implicitly, this assumes that the wires of the operator correspond to the global wire order. .. seealso:: :meth:`~.ECR.matrix` Return type: tensor_like **Example** >>> print(qml.ECR.compute_matrix()) [[0+0.j 0.+0.j 1/sqrt(2)+0.j 0.+1j/sqrt(2)] [0.+0.j 0.+0.j 0.+1.j/sqrt(2) 1/sqrt(2)+0.j] [1/sqrt(2)+0.j 0.-1.j/sqrt(2) 0.+0.j 0.+0.j] [0.-1/sqrt(2)j 1/sqrt(2)+0.j 0.+0.j 0.+0.j]] """returnnp.array([[0,0,INV_SQRT2,INV_SQRT2*1j],[0,0,INV_SQRT2*1j,INV_SQRT2],[INV_SQRT2,-INV_SQRT2*1j,0,0],[-INV_SQRT2*1j,INV_SQRT2,0,0],])
[docs]@staticmethoddefcompute_eigvals()->np.ndarray:r"""Eigenvalues of the operator in the computational basis (static method). If :attr:`diagonalizing_gates` are specified and implement a unitary :math:`U^{\dagger}`, the operator can be reconstructed as .. math:: O = U \Sigma U^{\dagger}, where :math:`\Sigma` is the diagonal matrix containing the eigenvalues. Otherwise, no particular order for the eigenvalues is guaranteed. .. seealso:: :meth:`~.ECR.eigvals` Returns: array: eigenvalues **Example** >>> print(qml.ECR.compute_eigvals()) [1, -1, 1, -1] """returnnp.array([1,-1,1,-1])
[docs]@staticmethoddefcompute_decomposition(wires:WiresLike)->list[qml.operation.Operator]:r"""Representation of the operator as a product of other operators (static method). .. math:: O = O_1 O_2 \dots O_n. .. seealso:: :meth:`~.ECR.decomposition`. Args: wires (Iterable, Wires): wires that the operator acts on Returns: list[Operator]: decomposition into lower level operations **Example:** >>> print(qml.ECR.compute_decomposition((0,1))) [Z(0), CNOT(wires=[0, 1]), SX(1), RX(1.5707963267948966, wires=[0]), RY(1.5707963267948966, wires=[0]), RX(1.5707963267948966, wires=[0])] """pi=np.pireturn[Z(wires=[wires[0]]),qml.CNOT(wires=[wires[0],wires[1]]),SX(wires=[wires[1]]),qml.RX(pi/2,wires=[wires[0]]),qml.RY(pi/2,wires=[wires[0]]),qml.RX(pi/2,wires=[wires[0]]),]
[docs]classISWAP(Operation):r"""ISWAP(wires) The i-swap operator .. math:: ISWAP = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & i & 0\\ 0 & i & 0 & 0\\ 0 & 0 & 0 & 1 \end{bmatrix}. **Details:** * Number of wires: 2 * Number of parameters: 0 Args: wires (Sequence[int]): the wires the operation acts on """num_wires=2num_params=0"""int: Number of trainable parameters that the operator depends on."""batch_size=None@propertydefpauli_rep(self):ifself._pauli_repisNone:self._pauli_rep=qml.pauli.PauliSentence({qml.pauli.PauliWord({}):0.5,qml.pauli.PauliWord({self.wires[0]:"X",self.wires[1]:"X"}):0.5j,qml.pauli.PauliWord({self.wires[0]:"Y",self.wires[1]:"Y"}):0.5j,qml.pauli.PauliWord({self.wires[0]:"Z",self.wires[1]:"Z"}):0.5,})returnself._pauli_rep
[docs]@staticmethod@lru_cache()defcompute_matrix()->np.ndarray:# pylint: disable=arguments-differr"""Representation of the operator as a canonical matrix in the computational basis (static method). The canonical matrix is the textbook matrix representation that does not consider wires. Implicitly, this assumes that the wires of the operator correspond to the global wire order. .. seealso:: :meth:`~.ISWAP.matrix` Returns: ndarray: matrix **Example** >>> print(qml.ISWAP.compute_matrix()) [[1.+0.j 0.+0.j 0.+0.j 0.+0.j] [0.+0.j 0.+0.j 0.+1.j 0.+0.j] [0.+0.j 0.+1.j 0.+0.j 0.+0.j] [0.+0.j 0.+0.j 0.+0.j 1.+0.j]] """returnnp.array([[1,0,0,0],[0,0,1j,0],[0,1j,0,0],[0,0,0,1]])
[docs]@staticmethoddefcompute_eigvals()->np.ndarray:# pylint: disable=arguments-differr"""Eigenvalues of the operator in the computational basis (static method). If :attr:`diagonalizing_gates` are specified and implement a unitary :math:`U^{\dagger}`, the operator can be reconstructed as .. math:: O = U \Sigma U^{\dagger}, where :math:`\Sigma` is the diagonal matrix containing the eigenvalues. Otherwise, no particular order for the eigenvalues is guaranteed. .. seealso:: :meth:`~.ISWAP.eigvals` Returns: array: eigenvalues **Example** >>> print(qml.ISWAP.compute_eigvals()) [1j, -1j, 1, 1] """returnnp.array([1j,-1j,1,1])
[docs]@staticmethoddefcompute_decomposition(wires:WiresLike)->list[qml.operation.Operator]:r"""Representation of the operator as a product of other operators (static method). .. math:: O = O_1 O_2 \dots O_n. .. seealso:: :meth:`~.ISWAP.decomposition`. Args: wires (Iterable, Wires): wires that the operator acts on Returns: list[Operator]: decomposition into lower level operations **Example:** >>> print(qml.ISWAP.compute_decomposition((0,1))) [S(0), S(1), H(0), CNOT(wires=[0, 1]), CNOT(wires=[1, 0]), H(1)] """return[S(wires=wires[0]),S(wires=wires[1]),Hadamard(wires=wires[0]),qml.CNOT(wires=[wires[0],wires[1]]),qml.CNOT(wires=[wires[1],wires[0]]),Hadamard(wires=wires[1]),]
[docs]classSISWAP(Operation):r"""SISWAP(wires) The square root of i-swap operator. Can also be accessed as ``qml.SQISW`` .. math:: SISWAP = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1/ \sqrt{2} & i/\sqrt{2} & 0\\ 0 & i/ \sqrt{2} & 1/ \sqrt{2} & 0\\ 0 & 0 & 0 & 1 \end{bmatrix}. **Details:** * Number of wires: 2 * Number of parameters: 0 Args: wires (Sequence[int]): the wires the operation acts on """num_wires=2num_params=0"""int: Number of trainable parameters that the operator depends on."""batch_size=None@propertydefpauli_rep(self):ifself._pauli_repisNone:self._pauli_rep=qml.pauli.PauliSentence({qml.pauli.PauliWord({self.wires[0]:"I",self.wires[1]:"I"}):0.5+0.5*INV_SQRT2,qml.pauli.PauliWord({self.wires[0]:"X",self.wires[1]:"X"}):0.5j*INV_SQRT2,qml.pauli.PauliWord({self.wires[0]:"Y",self.wires[1]:"Y"}):0.5j*INV_SQRT2,qml.pauli.PauliWord({self.wires[0]:"Z",self.wires[1]:"Z"}):0.5-0.5*INV_SQRT2,})returnself._pauli_rep
[docs]@staticmethod@lru_cache()defcompute_matrix()->np.ndarray:# pylint: disable=arguments-differr"""Representation of the operator as a canonical matrix in the computational basis (static method). The canonical matrix is the textbook matrix representation that does not consider wires. Implicitly, this assumes that the wires of the operator correspond to the global wire order. .. seealso:: :meth:`~.SISWAP.matrix` Returns: ndarray: matrix **Example** >>> print(qml.SISWAP.compute_matrix()) [[1.+0.j 0.+0.j 0.+0.j 0.+0.j] [0.+0.j 0.70710678+0.j 0.+0.70710678j 0.+0.j] [0.+0.j 0.+0.70710678j 0.70710678+0.j 0.+0.j] [0.+0.j 0.+0.j 0.+0.j 1.+0.j]] """returnnp.array([[1,0,0,0],[0,INV_SQRT2,INV_SQRT2*1j,0],[0,INV_SQRT2*1j,INV_SQRT2,0],[0,0,0,1],])
[docs]@staticmethoddefcompute_eigvals()->np.ndarray:# pylint: disable=arguments-differr"""Eigenvalues of the operator in the computational basis (static method). If :attr:`diagonalizing_gates` are specified and implement a unitary :math:`U^{\dagger}`, the operator can be reconstructed as .. math:: O = U \Sigma U^{\dagger}, where :math:`\Sigma` is the diagonal matrix containing the eigenvalues. Otherwise, no particular order for the eigenvalues is guaranteed. .. seealso:: :meth:`~.SISWAP.eigvals` Returns: array: eigenvalues **Example** >>> print(qml.SISWAP.compute_eigvals()) [0.70710678+0.70710678j 0.70710678-0.70710678j 1.+0.j 1.+0.j] """returnnp.array([INV_SQRT2*(1+1j),INV_SQRT2*(1-1j),1,1])
[docs]@staticmethoddefcompute_decomposition(wires:WiresLike)->list[qml.operation.Operator]:r"""Representation of the operator as a product of other operators (static method). .. math:: O = O_1 O_2 \dots O_n. .. seealso:: :meth:`~.SISWAP.decomposition`. Args: wires (Iterable, Wires): wires that the operator acts on Returns: list[Operator]: decomposition into lower level operations **Example:** >>> print(qml.SISWAP.compute_decomposition((0,1))) [SX(0)), RZ(1.5707963267948966, wires=[0]), CNOT(wires=[0, 1]), SX(0), RZ(5.497787143782138, wires=[0]), SX(0), RZ(1.5707963267948966, wires=[0]), SX(1), RZ(5.497787143782138, wires=[1]), CNOT(wires=[0, 1]), SX(0), SX(1)] """return[SX(wires=wires[0]),qml.RZ(np.pi/2,wires=wires[0]),qml.CNOT(wires=[wires[0],wires[1]]),SX(wires=wires[0]),qml.RZ(7*np.pi/4,wires=wires[0]),SX(wires=wires[0]),qml.RZ(np.pi/2,wires=wires[0]),SX(wires=wires[1]),qml.RZ(7*np.pi/4,wires=wires[1]),qml.CNOT(wires=[wires[0],wires[1]]),SX(wires=wires[0]),SX(wires=wires[1]),]